<template>
  <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
    <!-- Breadcrumb -->
    <div id="ViewBreadcrumb" class="mb-8">
      <h1 class="text-lg text-center font-light relative px-7">
        <!-- Cancel -->
        <button
          @click="$router.go(-1)"
          class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
        >
          <fa icon="chevron-left"></fa>
        </button>
        Import Existing Identifier
      </h1>
    </div>
    <!-- Import Account Form -->
    <p class="text-center text-xl mb-4 font-light">
      Enter your seed phrase below to import your identifier on this device.
    </p>
    <!-- id used by puppeteer test script -->
    <textarea
      id="seed-input"
      type="text"
      placeholder="Seed Phrase"
      class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
      v-model="mnemonic"
    />

    <h3
      class="text-sm uppercase font-semibold mb-3"
      @click="showAdvanced = !showAdvanced"
    >
      Advanced
    </h3>
    <div v-if="showAdvanced">
      Enter a custom derivation path
      <input
        type="text"
        class="block w-full rounded border border-slate-400 mb-2 px-3 py-2"
        v-model="derivationPath"
      />
      <span class="ml-4">
        For previous uPort or Endorser users,
        <a
          @click="derivationPath = UPORT_DERIVATION_PATH"
          class="text-blue-500"
        >
          click here to use that value.
        </a>
      </span>

      <div class="mt-4" v-if="numAccounts == 1">
        <input type="checkbox" class="mr-2" v-model="shouldErase" />
        <label>Erase the previous identifier.</label>
      </div>

      <div v-if="isNotProdServer()" class="mt-4 text-blue-500">
        <!-- if they click this, fill in the mnemonic seed-input with the test mnemonic -->
        <button @click="mnemonic = TEST_USER_0_MNEMONIC">
          Use mnemonic for Test User #0
        </button>
      </div>
    </div>

    <div class="mt-8">
      <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
        <button
          @click="fromMnemonic()"
          class="block w-full text-center text-lg font-bold uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md"
        >
          Import
        </button>
        <button
          @click="onCancelClick()"
          type="button"
          class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
        >
          Cancel
        </button>
      </div>
    </div>
  </section>
</template>

<script lang="ts">
import { Component, Vue } from "vue-facing-decorator";
import { Router } from "vue-router";

import { AppString, NotificationIface } from "@/constants/app";
import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import {
  DEFAULT_ROOT_DERIVATION_PATH,
  deriveAddress,
  newIdentifier,
} from "@/libs/crypto";

@Component({
  components: {},
})
export default class ImportAccountView extends Vue {
  TEST_USER_0_MNEMONIC =
    "rigid shrug mobile smart veteran half all pond toilet brave review universe ship congress found yard skate elite apology jar uniform subway slender luggage";
  UPORT_DERIVATION_PATH = "m/7696500'/0'/0'/0'"; // for legacy imports, likely never used

  AppString = AppString;

  $notify!: (notification: NotificationIface, timeout?: number) => void;

  apiServer = "";
  address = "";
  derivationPath = DEFAULT_ROOT_DERIVATION_PATH;
  mnemonic = "";
  numAccounts = 0;
  privateHex = "";
  publicHex = "";
  showAdvanced = false;
  shouldErase = false;

  async created() {
    await accountsDB.open();
    this.numAccounts = await accountsDB.accounts.count();
    // get the server, to help with import on the test server
    const settings = await retrieveSettingsForActiveAccount();
    this.apiServer = settings.apiServer || "";
  }

  public onCancelClick() {
    (this.$router as Router).back();
  }

  public isNotProdServer() {
    return this.apiServer !== AppString.PROD_ENDORSER_API_SERVER;
  }

  public async fromMnemonic() {
    const mne: string = this.mnemonic.trim().toLowerCase();
    try {
      [this.address, this.privateHex, this.publicHex] = deriveAddress(
        mne,
        this.derivationPath,
      );

      const newId = newIdentifier(
        this.address,
        this.publicHex,
        this.privateHex,
        this.derivationPath,
      );

      await accountsDB.open();
      if (this.shouldErase) {
        await accountsDB.accounts.clear();
      }
      await accountsDB.accounts.add({
        dateCreated: new Date().toISOString(),
        derivationPath: this.derivationPath,
        did: newId.did,
        identity: JSON.stringify(newId),
        mnemonic: mne,
        publicKeyHex: newId.keys[0].publicKeyHex,
      });

      // record that as the active DID
      await db.open();
      await db.settings.update(MASTER_SETTINGS_KEY, {
        activeDid: newId.did,
      });
      (this.$router as Router).push({ name: "account" });
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
    } catch (err: any) {
      console.error("Error saving mnemonic & updating settings:", err);
      if (err == "Error: invalid mnemonic") {
        this.$notify(
          {
            group: "alert",
            type: "danger",
            title: "Invalid Mnemonic",
            text: "Please check your mnemonic and try again.",
          },
          -1,
        );
      } else {
        this.$notify(
          {
            group: "alert",
            type: "danger",
            title: "Error",
            text: "Got an error creating that identifier.",
          },
          -1,
        );
      }
    }
  }
}
</script>
