import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
import { marker } from '@biesbjerg/ngx-translate-extract-marker';
import { base64 } from 'rfc4648';
import { verify_passive_identity_signature } from '../../crypto/auth/identity';
import { AccountTrustConfigDumpArgs } from '../../crypto/context/account_trust/args';
import { ACCOUNT_TRUST_CRYPTO_CONTEXT } from '../../crypto/context/account_trust/__init__';
import { AbstractAccountKeyring } from '../../crypto/keyring/account_base';
import { AccountService } from '../../server-services/account.service';
import { AuthService } from '../../server-services/auth.service';
import { AccountAvatarRecord } from '../../server-services/query-records/account-records';
import { addTrustQuery } from '../../server-services/querys';
import { DialogService } from '../../services/dialog.service';
import { ServerRestApiService } from '../../services/server-rest-api.service';
import { SnackBarService } from '../../services/snackbar.service';
import msgpack from 'msgpack-lite';

@Component({
  selector: 'app-verify-signature-dialog',
  templateUrl: './verify-signature-dialog.component.html',
  styleUrls: ['./verify-signature-dialog.component.scss'],
})
export class VerifySignatureDialogComponent implements OnInit {
  constructor(
    @Inject(MAT_DIALOG_DATA) public avatar: AccountAvatarRecord,
    private dialogService: DialogService,
    private authService: AuthService,
    private accountService: AccountService,
    private serverRestApiService: ServerRestApiService,
    private snackBarService: SnackBarService
  ) {}

  public signature: string = '';

  ngOnInit(): void {}

  public checkError: boolean = false;
  public timestamp: number;

  public checkInput() {
    this.checkError = false;
    this.timestamp = undefined;

    try {
      let { identity, signature } = msgpack.decode(base64.parse(this.signature));
      this.accountService.getPeerKeyring(this.avatar.id).then((peer_kr) => {
        verify_passive_identity_signature(peer_kr, identity, signature).then(
          (passiveIdentityType) => {
            if (passiveIdentityType) {
              this.timestamp = passiveIdentityType.timestamp;
            } else {
              throw 'could not verify';
            }
          }
        );
      });
    } catch (e) {
      console.warn('check error', e);
      this.checkError = true;
    }
  }

  public save() {
    this.timestamp &&
      this.dialogService
        .openConfirmDialog(
          marker('Confirm'),
          marker("Cryptographic trust signatures can't be undone!") + ' ' + marker('Are you sure?')
        )
        .subscribe((sure) => {
          if (sure) {
            this.accountService
              .getPeerKeyring(this.avatar.id)
              .then((peer_kr) => {
                let bestTrustRoot;

                // best-trust-root is the first public key in the peer keyring that exists of the TRUST_KEY_VERSIONS
                for (let i = 0; i < AbstractAccountKeyring.TRUST_KEY_VERSIONS.length; i++) {
                  let trustKeyV = AbstractAccountKeyring.TRUST_KEY_VERSIONS[i];
                  if (trustKeyV in peer_kr._public_keys) {
                    bestTrustRoot = trustKeyV;
                    break;
                  }
                }

                if (bestTrustRoot !== undefined) {
                  return ACCOUNT_TRUST_CRYPTO_CONTEXT.dump(
                    new AccountTrustConfigDumpArgs(
                      this.authService.getSelfAccountKeyring(),
                      peer_kr,
                      bestTrustRoot
                    )
                  ).then((trust) => {
                    return this.serverRestApiService
                      .mutate({
                        query: addTrustQuery,
                        variables: {
                          peerId: this.avatar.id,
                          trust,
                        },
                      })
                      .then(() => {
                        this.snackBarService.showSnackbar(marker('Successful save'));
                      });
                  });
                } else {
                  console.error('could not find best trust root');
                  throw 'could not find best trust root';
                }
              })
              .catch((e) => {
                console.error('error', e);
                this.snackBarService.showSnackbar(marker('Error during the operation'));
              });
          }
        });
  }
}
