<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
          class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
          @click="$router.go(-1)"
        >
          <font-awesome icon="chevron-left"></font-awesome>
        </button>
        Derive from Existing Identity
      </h1>
    </div>
    <!-- Import Account Form -->

    <div>
      <p class="text-center text-xl mb-4 font-light">
        Will increment the maximum known derivation path from the existing seed.
      </p>

      <p v-if="didArrays.length > 1">
        Choose existing DIDs from same seed phrase to compute derivation.
      </p>
      <ul class="mb-4">
        <li
          v-for="dids in didArrays"
          :key="dids[0]"
          class="block bg-slate-100 rounded-md flex items-center px-4 py-3 mb-2"
          @click="switchAccount(dids[0])"
        >
          <font-awesome
            v-if="dids[0] == selectedArrayFirstDid"
            icon="circle"
            class="fa-fw text-blue-500 text-xl mr-3"
          ></font-awesome>
          <font-awesome
            v-else
            icon="circle"
            class="fa-fw text-slate-400 text-xl mr-3"
          ></font-awesome>
          <span class="overflow-hidden">
            <div class="text-sm text-slate-500 truncate">
              <code>{{ dids.join(",") }}</code>
            </div>
          </span>
        </li>
      </ul>
    </div>
    <div class="mt-8">
      <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
        <button
          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"
          @click="incrementDerivation()"
        >
          Increment and Import
        </button>
        <button
          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"
          @click="onCancelClick()"
        >
          Cancel
        </button>
      </div>
    </div>
  </section>
</template>

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

import {
  DEFAULT_ROOT_DERIVATION_PATH,
  deriveAddress,
  newIdentifier,
  nextDerivationPath,
} from "../libs/crypto";
import { accountsDBPromise, db } from "../db/index";
import { MASTER_SETTINGS_KEY } from "../db/tables/settings";
import { retrieveAllFullyDecryptedAccounts } from "../libs/util";

@Component({
  components: {},
})
export default class ImportAccountView extends Vue {
  $route!: RouteLocationNormalizedLoaded;
  $router!: Router;

  derivationPath = DEFAULT_ROOT_DERIVATION_PATH;
  didArrays: Array<Array<string>> = [];
  selectedArrayFirstDid = "";

  async mounted() {
    const accounts = await retrieveAllFullyDecryptedAccounts(); // let's match derived accounts differently so we don't need the private info
    const seedDids: Record<string, Array<string>> = {};
    accounts.forEach((account) => {
      const prevDids: Array<string> = seedDids[account.mnemonic] || [];
      seedDids[account.mnemonic] = prevDids.concat([account.did]);
    });
    this.didArrays = Object.values(seedDids);
    this.selectedArrayFirstDid = this.didArrays[0][0];
  }

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

  public switchAccount(did: string) {
    this.selectedArrayFirstDid = did;
  }

  public async incrementDerivation() {
    // find the maximum derivation path for the selected DIDs
    const selectedArray: Array<string> =
      this.didArrays.find((dids) => dids[0] === this.selectedArrayFirstDid) ||
      [];
    const accountsDB = await accountsDBPromise; // let's match derived accounts differently so we don't need the private info
    const allMatchingAccounts = await accountsDB.accounts
      .where("did")
      .anyOf(...selectedArray)
      .toArray();
    const accountWithMaxDeriv = allMatchingAccounts[0];
    allMatchingAccounts.slice(1).forEach((account) => {
      if (account.derivationPath > accountWithMaxDeriv.derivationPath) {
        accountWithMaxDeriv.derivationPath = account.derivationPath;
      }
    });
    // increment the last number in that max derivation path
    const newDerivPath = nextDerivationPath(
      accountWithMaxDeriv.derivationPath as string,
    );

    const mne: string = accountWithMaxDeriv.mnemonic as string;

    const [address, privateHex, publicHex] = deriveAddress(mne, newDerivPath);

    const newId = newIdentifier(address, publicHex, privateHex, newDerivPath);

    try {
      await accountsDB.accounts.add({
        dateCreated: new Date().toISOString(),
        derivationPath: newDerivPath,
        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.push({ name: "account" });
    } catch (err) {
      console.error("Error saving mnemonic & updating settings:", err);
    }
  }
}
</script>
