/**
 * Seed Input Screen - Initial screen for wallet seed phrase entry.
 * 
 * Allows users to enter their BIP39 seed phrase to initialize the wallet,
 * or select from previously saved mnemonic files on disk.
 */

import React, { useState, useCallback, useEffect } from 'react';
import { Box, Text } from 'ink';
import TextInput from '../components/TextInput.js';
import { Button } from '../components/Button.js';
import { useNavigation } from '../hooks/useNavigation.js';
import { useAppContext, useStatus } from '../hooks/useAppContext.js';
import { useBlockableInput } from '../hooks/useInputLayer.js';
import { colors, logo } from '../theme.js';

import fs from 'fs';
import path from 'path';
import { createMnemonicFile } from '../../cli/mnemonic.js';
import { getMnemonicsDir } from '../../utils/paths.js';
import { BCHMnemonicURL } from '../../utils/bch-mnemonic-url.js';
import { encodeBip39Mnemonic } from '@bitauth/libauth';

/**
 * Status message type.
 */
type StatusType = 'idle' | 'loading' | 'error' | 'success';

/**
 * Parsed mnemonic file entry with the derived seed phrase ready for wallet init.
 */
interface MnemonicFileEntry {
  filename: string;
  /** Friendly label derived from filename or the URL comment field. */
  label: string;
  /** The BIP39 mnemonic phrase derived from the file's entropy. */
  mnemonic: string;
}

/**
 * Focus sections the user can tab between.
 * When saved wallets exist the file list is shown first.
 */
type FocusSection = 'files' | 'input' | 'saveCheckbox' | 'button';

/**
 * Reads mnemonic-* files from ~/.config/xo-cli/mnemonics/ (same as xo-cli),
 * then from cwd for legacy installs. Parses each as a BCHMnemonicURL.
 */
function loadMnemonicFiles(): MnemonicFileEntry[] {
  const dirs = [getMnemonicsDir(), process.cwd()];
  const seenBasenames = new Set<string>();
  const entries: MnemonicFileEntry[] = [];

  for (const dir of dirs) {
    if (!fs.existsSync(dir)) continue;
    const filenames = fs
      .readdirSync(dir)
      .filter((f) => f.startsWith('mnemonic-'));
    for (const filename of filenames) {
      if (seenBasenames.has(filename)) continue;
      try {
        const content = fs.readFileSync(path.join(dir, filename), 'utf-8').trim();
        const parsed = BCHMnemonicURL.fromURL(content);
        const raw = parsed.toObject();

        const mnemonicResult = encodeBip39Mnemonic(raw.entropy);
        if (typeof mnemonicResult === 'string') continue;

        /** Use the URL comment as the label, falling back to a cleaned-up filename. */
        const label = raw.comment
          ?? filename.replace(/^mnemonic-/, '').replace(/\.[^.]+$/, '');

        entries.push({ filename, label, mnemonic: mnemonicResult.phrase });
        seenBasenames.add(filename);
      } catch {
        // Skip files that can't be parsed
      }
    }
  }
  return entries;
}

/**
 * Seed Input Screen Component.
 * Provides seed phrase entry for wallet initialization and a selectable
 * list of previously saved mnemonic files.
 */
export function SeedInputScreen(): React.ReactElement {
  const { navigate } = useNavigation();
  const { initializeWallet } = useAppContext();
  const { setStatus } = useStatus();
  
  // State
  const [seedPhrase, setSeedPhrase] = useState('');
  const [statusMessage, setStatusMessage] = useState('');
  const [statusType, setStatusType] = useState<StatusType>('idle');
  const [isSubmitting, setIsSubmitting] = useState(false);

  // Mnemonic file list state
  const [mnemonicFiles, setMnemonicFiles] = useState<MnemonicFileEntry[]>([]);
  const [selectedFileIndex, setSelectedFileIndex] = useState(0);

  /** When set, manual seed is written to ~/.config/xo-cli/mnemonics/ after a successful unlock. */
  const [saveMnemonicChecked, setSaveMnemonicChecked] = useState(false);

  // Focus: when saved wallets exist default to the file list, otherwise the input.
  const [focusedSection, setFocusedSection] = useState<FocusSection>('input');

  useEffect(() => {
    const entries = loadMnemonicFiles();
    setMnemonicFiles(entries);
    if (entries.length > 0) setFocusedSection('files');
  }, []);

  /**
   * The ordered list of focusable sections (files section only when entries exist).
   */
  const focusSections: FocusSection[] = mnemonicFiles.length > 0
    ? ['files', 'input', 'saveCheckbox', 'button']
    : ['input', 'saveCheckbox', 'button'];

  /**
   * Shows a status message with the given type.
   */
  const showStatus = useCallback((message: string, type: StatusType) => {
    setStatusMessage(message);
    setStatusType(type);
  }, []);

  /**
   * Shared wallet initialization handler used by both manual entry and file selection.
   */
  const doInitialize = useCallback(
    async (seed: string, options?: { saveMnemonic?: boolean }) => {
      showStatus('Initializing wallet...', 'loading');
      setStatus('Initializing wallet...');
      setIsSubmitting(true);

      try {
        await initializeWallet(seed);

        let statusText = 'Wallet initialized successfully!';
        if (options?.saveMnemonic) {
          try {
            const savedAs = createMnemonicFile(getMnemonicsDir(), seed);
            setMnemonicFiles(loadMnemonicFiles());
            statusText = `Wallet initialized! Mnemonic saved as ${savedAs}`;
          } catch (saveErr) {
            const saveMsg =
              saveErr instanceof Error ? saveErr.message : String(saveErr);
            statusText = `Wallet initialized, but could not save mnemonic: ${saveMsg}`;
          }
        }

        showStatus(statusText, 'success');
        setStatus('Wallet ready');
        setSeedPhrase('');
        setSaveMnemonicChecked(false);

        setTimeout(() => {
          navigate('wallet');
        }, 500);
      } catch (error) {
        const message =
          error instanceof Error ? error.message : 'Failed to initialize wallet';
        showStatus(message, 'error');
        setStatus('Initialization failed');
        setIsSubmitting(false);
      }
    },
    [initializeWallet, navigate, showStatus, setStatus],
  );

  /**
   * Handles manual seed phrase submission with validation.
   */
  const handleSubmit = useCallback(async () => {
    const seed = seedPhrase.trim();

    if (!seed) {
      showStatus('Please enter your seed phrase', 'error');
      return;
    }

    const wordCount = seed.split(/\s+/).length;
    if (wordCount !== 12 && wordCount !== 24) {
      showStatus(`Invalid seed phrase. Expected 12 or 24 words, got ${wordCount}`, 'error');
      return;
    }

    await doInitialize(seed, { saveMnemonic: saveMnemonicChecked });
  }, [seedPhrase, saveMnemonicChecked, doInitialize, showStatus]);

  /**
   * Handles selecting a mnemonic file from the list.
   */
  const handleFileSelect = useCallback(async (index: number) => {
    const entry = mnemonicFiles[index];
    if (!entry) return;
    await doInitialize(entry.mnemonic);
  }, [mnemonicFiles, doInitialize]);

  // Keyboard navigation
  useBlockableInput((_input, key) => {
    if (isSubmitting) return;

    // Tab / Shift-Tab to cycle focus sections
    if (key.tab) {
      setFocusedSection((prev) => {
        const idx = focusSections.indexOf(prev);
        const next = key.shift
          ? (idx - 1 + focusSections.length) % focusSections.length
          : (idx + 1) % focusSections.length;
        return focusSections[next]!;
      });
      return;
    }

    // Space or Enter toggles "save mnemonic" when that row is focused
    if (focusedSection === 'saveCheckbox') {
      if (_input === ' ' || key.return) {
        setSaveMnemonicChecked((v) => !v);
        return;
      }
    }

    // Arrow keys inside the file list
    if (focusedSection === 'files' && mnemonicFiles.length > 0) {
      if (key.upArrow) {
        setSelectedFileIndex((prev) => Math.max(0, prev - 1));
        return;
      }
      if (key.downArrow) {
        setSelectedFileIndex((prev) => Math.min(mnemonicFiles.length - 1, prev + 1));
        return;
      }
      if (key.return) {
        handleFileSelect(selectedFileIndex);
        return;
      }
    }

    // Enter on button submits manual seed
    if (key.return && focusedSection === 'button') {
      handleSubmit();
    }
  });

  // Derived style helpers
  const statusColor = statusType === 'error' ? colors.error :
                      statusType === 'success' ? colors.success :
                      statusType === 'loading' ? colors.info :
                      colors.textMuted;

  const inputBorderColor = statusType === 'error' ? colors.error :
                           statusType === 'success' ? colors.success :
                           focusedSection === 'input' ? colors.focus :
                           colors.borderMuted;

  return (
    <Box flexDirection='column' alignItems='center' paddingY={1}>
      {/* Logo */}
      <Box marginBottom={1}>
        <Text color={colors.primary}>{logo}</Text>
      </Box>

      {/* Title */}
      <Text color={colors.text} bold>Welcome to XO Wallet CLI</Text>
      <Text color={colors.textMuted}>Enter your seed phrase or select a saved wallet</Text>

      <Box marginY={1} />

      <Box flexDirection='column' width={64}>
        {/* ── Saved Wallets ─────────────────────────────────── */}
        {mnemonicFiles.length > 0 && (
          <Box flexDirection='column' marginBottom={1}>
            <Box marginBottom={1}>
              <Text color={colors.primary} bold>
                {'▸ '}Saved Wallets
              </Text>
              <Text color={colors.textMuted}> ({mnemonicFiles.length})</Text>
            </Box>

            <Box
              flexDirection='column'
              borderStyle='single'
              borderColor={focusedSection === 'files' ? colors.focus : colors.borderMuted}
              paddingX={1}
            >
              {mnemonicFiles.map((entry, idx) => {
                const isHighlighted = focusedSection === 'files' && idx === selectedFileIndex;

                return (
                  <Box key={entry.filename} paddingY={0}>
                    <Text
                      color={isHighlighted ? colors.bg : colors.textMuted}
                      backgroundColor={isHighlighted ? colors.focus : undefined}
                      bold={isHighlighted}
                    >
                      {isHighlighted ? ' ▶ ' : '   '}
                    </Text>
                    <Text
                      color={isHighlighted ? colors.bg : colors.text}
                      backgroundColor={isHighlighted ? colors.focus : undefined}
                      bold={isHighlighted}
                    >
                      {` ${entry.label} `}
                    </Text>
                    <Text
                      color={isHighlighted ? colors.bg : colors.textMuted}
                      backgroundColor={isHighlighted ? colors.focus : undefined}
                      dimColor={!isHighlighted}
                    >
                      {` (${entry.filename})`}
                    </Text>
                  </Box>
                );
              })}
            </Box>

            {focusedSection === 'files' && (
              <Box marginTop={0} paddingX={1}>
                <Text color={colors.textMuted} dimColor>
                  ↑↓ navigate • Enter: load wallet
                </Text>
              </Box>
            )}
          </Box>
        )}

        {/* ── Divider between sections ──────────────────────── */}
        {mnemonicFiles.length > 0 && (
          <Box marginBottom={1} justifyContent='center'>
            <Text color={colors.borderMuted}>{'─'.repeat(20)} or {'─'.repeat(20)}</Text>
          </Box>
        )}

        {/* ── Manual Seed Entry ─────────────────────────────── */}
        <Text color={colors.primary} bold>
          {'▸ '}Manual Entry
        </Text>
        <Box marginTop={1}>
          <Text color={colors.text}>Seed Phrase (12 or 24 words):</Text>
        </Box>
        <Box
          borderStyle='single'
          borderColor={inputBorderColor}
          paddingX={1}
          marginTop={1}
        >
          <TextInput
            value={seedPhrase}
            onChange={setSeedPhrase}
            onSubmit={handleSubmit}
            placeholder='Enter your seed phrase...'
            focus={focusedSection === 'input' && !isSubmitting}
          />
        </Box>

        {/* Save mnemonic checkbox (manual entry only; applies on Continue) */}
        <Box
          marginTop={1}
          paddingX={1}
          borderStyle='single'
          borderColor={
            focusedSection === 'saveCheckbox' ? colors.focus : colors.borderMuted
          }
        >
          <Text
            color={focusedSection === 'saveCheckbox' ? colors.focus : colors.text}
            bold={focusedSection === 'saveCheckbox'}
          >
            {saveMnemonicChecked ? '[x] ' : '[ ] '}
          </Text>
          <Text color={colors.text}>Save this mnemonic</Text>
          <Text color={colors.textMuted}> (~/.config/xo-cli/mnemonics/)</Text>
        </Box>
        {focusedSection === 'saveCheckbox' && (
          <Box marginTop={0} paddingX={1}>
            <Text color={colors.textMuted} dimColor>
              Space / Enter: toggle
            </Text>
          </Box>
        )}

        {/* Status message */}
        <Box marginTop={1} height={1}>
          {statusMessage && (
            <Text color={statusColor}>
              {statusType === 'loading' && '⏳ '}
              {statusType === 'error' && '✗ '}
              {statusType === 'success' && '✓ '}
              {statusMessage}
            </Text>
          )}
        </Box>

        {/* Submit button */}
        <Box justifyContent='center' marginTop={1}>
          <Button
            label='Continue'
            focused={focusedSection === 'button'}
            disabled={isSubmitting}
            shortcut='Enter'
          />
        </Box>
      </Box>

      {/* Help text */}
      <Box marginTop={2}>
        <Text color={colors.textMuted} dimColor>
          Tab: navigate • Enter: submit, load wallet, or toggle save • Space: toggle save • Esc: back
        </Text>
      </Box>
    </Box>
  );
}
