<!--
  SeedBackupView.vue - Seed Phrase Backup & Recovery Component
  
  Critical security component that allows users to view and backup their seed phrases
  and derivation paths. This is essential for account recovery and cross-device access.
  
  Key Features:
  - Seed phrase display with security warnings
  - Derivation path display for key generation
  - Clipboard integration for copying sensitive data
  - Security warnings and multi-account detection
  - Explicit reveal mechanism for sensitive data protection
  
  Security Considerations:
  - Contains highly sensitive cryptographic material
  - Required for account recovery workflows
  - Implements security best practices for sensitive data display
  - Provides appropriate warnings about seed phrase exposure
  
  Migration Status: ✅ Complete Enhanced Triple Migration Pattern
  - Phase 1: Database Migration (PlatformServiceMixin) ✅
  - Phase 2: SQL Abstraction (N/A - no raw SQL) ✅
  - Phase 3: Notification Migration (Helper system) ✅
  - Phase 4: Template Streamlining (Computed properties) ✅
  
  Author: Matthew Raymer
  Last Updated: 2025-07-09
-->

<template>
  <!-- CONTENT -->
  <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
    <!-- Sub View Heading -->
    <div class="flex gap-4 items-start mb-8">
      <h1 class="grow text-xl text-center font-semibold leading-tight">
        Seed Backup
      </h1>

      <!-- Back -->
      <a
        class="order-first text-lg text-center leading-none p-1"
        @click="goBack()"
      >
        <font-awesome icon="chevron-left" class="block text-center w-[1em]" />
      </a>

      <!-- Help button -->
      <router-link
        :to="{ name: 'help' }"
        class="block ms-auto text-sm text-center text-white bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-1.5 rounded-full"
      >
        <font-awesome icon="question" class="block text-center w-[1em]" />
      </router-link>
    </div>

    <div v-if="activeAccount">
      <p class="text-center mb-4">
        <b class="text-red-600">BEWARE!</b> Anyone who has this seed phrase will
        be able impersonate you and take over any digital holdings based on it.
        Reveal it when you are somewhere private, when only you can see your
        screen, and record it somewhere only you have access. A password manager
        is a good idea, and so is a piece of paper in a vault.
        <i
          >We recommend you do NOT take a screenshot or send it to any online
          service.</i
        >
      </p>

      <p v-if="numAccounts > 1">
        <b class="text-orange-600">Note:</b> You have more than one identifier
        stored in this browser. If they are all based on the same seed as the
        current identifier, this one backup is sufficient, as long as you also
        record the derivation path. However, if you have different seeds for
        other identifiers, you will have to back them up separately.
      </p>

      <div class="bg-slate-100 rounded-md overflow-hidden p-4 mb-4">
        <p v-if="showSeed" class="text-center text-slate-700 mt-2">
          {{ activeAccount.mnemonic }}
          <button v-show="!showCopiedSeed" @click="copySeedPhrase">
            <font-awesome icon="copy" :class="copyIconClass"></font-awesome>
          </button>
          <span v-show="showCopiedSeed" :class="copiedFeedbackClass">
            Copied
          </span>
          <br />
          <br />
          Derivation Path: {{ activeAccount.derivationPath }}
          <button v-show="!showCopiedDeri" @click="copyDerivationPath">
            <font-awesome icon="copy" :class="copyIconClass"></font-awesome>
          </button>
          <span v-show="showCopiedDeri" :class="copiedFeedbackClass"
            >Copied</span
          >
        </p>
        <button v-else :class="revealButtonClass" @click="revealSeed">
          Reveal my Seed Phrase
        </button>
      </div>
    </div>
    <div v-else>You do not have an active identity.</div>
  </section>
</template>

<script lang="ts">
import { Component, Vue } from "vue-facing-decorator";
import { copyToClipboard } from "../services/ClipboardService";

import QuickNav from "../components/QuickNav.vue";
import { NotificationIface } from "../constants/app";
import { Account } from "../db/tables/accounts";
import { PlatformServiceMixin } from "../utils/PlatformServiceMixin";
import { createNotifyHelpers, TIMEOUTS } from "../utils/notify";
import { NOTIFY_PROFILE_SEED_LOAD_ERROR } from "../constants/notifications";
import {
  retrieveAccountCount,
  retrieveFullyDecryptedAccount,
} from "../libs/util";
import { Router } from "vue-router";
import { logger } from "../utils/logger";

/**
 * SeedBackupView Component
 *
 * Critical security component that allows users to view and backup their seed phrases
 * and derivation paths. This is essential for account recovery and cross-device access.
 *
 * Key features:
 * - Seed phrase display with explicit reveal mechanism
 * - Derivation path display for key generation
 * - Clipboard integration for copying sensitive data
 * - Security warnings and multi-account detection
 * - Comprehensive error handling for loading failures
 *
 * Security Features:
 * - Seed phrases hidden by default until explicitly revealed
 * - Appropriate security warnings about seed phrase exposure
 * - No accidental data exposure in logs or error messages
 * - Secure clipboard operations with user feedback
 * - Multi-account awareness and warnings
 *
 * Database Operations:
 * - Account settings retrieval via PlatformServiceMixin
 * - Account count retrieval for multi-account detection
 * - Full account decryption for seed phrase access
 *
 * @author Matthew Raymer
 */
@Component({
  components: { QuickNav },
  mixins: [PlatformServiceMixin],
})
export default class SeedBackupView extends Vue {
  $notify!: (notification: NotificationIface, timeout?: number) => void;
  $router!: Router;
  activeAccount: Account | null | undefined = null;
  numAccounts = 0;
  showCopiedDeri = false;
  showCopiedSeed = false;
  showSeed = false;

  // Notification helper system
  notify!: ReturnType<typeof createNotifyHelpers>;

  /**
   * Computed property for consistent copy feedback styling
   * Used for both seed phrase and derivation path copy feedback
   */
  get copiedFeedbackClass(): string {
    return "text-sm text-green-500";
  }

  /**
   * Computed property for reveal button styling
   * Provides consistent button styling for seed phrase reveal
   */
  get revealButtonClass(): string {
    return "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";
  }

  /**
   * Computed property for copy button icon styling
   * Provides consistent icon styling for clipboard operations
   */
  get copyIconClass(): string {
    return "text-slate-400 fa-fw";
  }

  /**
   * Computed property for help button styling
   * Provides consistent styling for the help navigation button
   */
  get helpButtonClass(): string {
    return "text-xs 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-1.5 py-1 rounded-md ml-1";
  }

  /**
   * Vue created lifecycle hook
   *
   * Initializes component by loading account settings and data.
   * Retrieves active account information and account count for multi-account detection.
   * Handles errors gracefully with user notifications.
   */
  async created() {
    // Initialize notification helpers
    this.notify = createNotifyHelpers(this.$notify);

    try {
      let activeDid = "";

      // Get activeDid from new active_identity table (ActiveDid migration)
      const activeIdentity = await this.$getActiveIdentity();
      activeDid = activeIdentity.activeDid || "";

      this.numAccounts = await retrieveAccountCount();
      this.activeAccount = await retrieveFullyDecryptedAccount(activeDid);
    } catch (err: unknown) {
      logger.error("Got an error loading an identifier:", err);
      this.notify.error(
        NOTIFY_PROFILE_SEED_LOAD_ERROR.message,
        TIMEOUTS.STANDARD,
      );
    }
  }

  /**
   * Navigates back to the previous page
   * Provides consistent navigation behavior for the back button
   */
  goBack(): void {
    this.$router.back();
  }

  /**
   * Reveals the seed phrase to the user
   * Sets showSeed to true to display the sensitive seed phrase data
   * Updates the hasBackedUpSeed setting to true to track that user has backed up
   */
  async revealSeed(): Promise<void> {
    this.showSeed = true;

    // Update the account setting to track that user has backed up their seed
    try {
      // Get activeDid from new active_identity table (ActiveDid migration)
      const activeIdentity = await this.$getActiveIdentity();
      if (activeIdentity.activeDid) {
        await this.$saveUserSettings(activeIdentity.activeDid, {
          hasBackedUpSeed: true,
        });
      }
    } catch (err: unknown) {
      logger.error("Failed to update hasBackedUpSeed setting:", err);
      // Don't show error to user as this is not critical to the main functionality
      // The seed phrase is still revealed, just the tracking won't work
    }
  }

  /**
   * Copies seed phrase to clipboard with user feedback
   * Handles clipboard operation for the mnemonic seed phrase
   */
  copySeedPhrase(): void {
    this.doCopyTwoSecRedo(
      this.activeAccount?.mnemonic as string,
      () => (this.showCopiedSeed = !this.showCopiedSeed),
    );
  }

  /**
   * Copies derivation path to clipboard with user feedback
   * Handles clipboard operation for the derivation path
   */
  copyDerivationPath(): void {
    this.doCopyTwoSecRedo(
      this.activeAccount?.derivationPath as string,
      () => (this.showCopiedDeri = !this.showCopiedDeri),
    );
  }

  /**
   * Copies text to clipboard and provides temporary user feedback
   *
   * @param text - The text to copy to clipboard
   * @param fn - Callback function to execute for feedback (called twice - immediately and after 2 seconds)
   */
  async doCopyTwoSecRedo(text: string, fn: () => void) {
    fn();
    try {
      await copyToClipboard(text);
      setTimeout(fn, 2000);
    } catch (error) {
      this.$logAndConsole(`Error copying to clipboard: ${error}`, true);
      this.notify.error("Failed to copy to clipboard.");
    }
  }
}
</script>
