import { type KeyboardEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';

import LottieAnimation from '../components/LottieAnimation';
import { persistLocalWalletFromMnemonic } from '../features/wallet/setupLocalWalletFromMnemonic';
import { useCoreState } from '../providers/CoreStateProvider';
import {
  generateMnemonicPhrase,
  MNEMONIC_GENERATE_WORD_COUNT,
  validateMnemonicPhrase,
} from '../utils/cryptoKeys';

/** Allowed BIP39 phrase lengths for import (includes legacy 24-word backups). */
const BIP39_IMPORT_LENGTHS = [12, 15, 18, 21, 24] as const;

const IMPORT_SLOTS_INITIAL = MNEMONIC_GENERATE_WORD_COUNT;

const Mnemonic = () => {
  const navigate = useNavigate();
  const { snapshot, setEncryptionKey } = useCoreState();
  const user = snapshot.currentUser;
  const [mode, setMode] = useState<'generate' | 'import'>('generate');
  const [copied, setCopied] = useState(false);
  const [confirmed, setConfirmed] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Generate mode state
  const mnemonic = useMemo(() => generateMnemonicPhrase(), []);
  const words = useMemo(() => mnemonic.split(' '), [mnemonic]);

  // Import mode state
  const [importWords, setImportWords] = useState<string[]>(Array(IMPORT_SLOTS_INITIAL).fill(''));
  const [importValid, setImportValid] = useState<boolean | null>(null);
  const inputRefs = useRef<(HTMLInputElement | null)[]>([]);

  useEffect(() => {
    if (copied) {
      const timer = setTimeout(() => setCopied(false), 3000);
      return () => clearTimeout(timer);
    }
  }, [copied]);

  // Reset state when switching modes
  useEffect(() => {
    setConfirmed(false);
    setError(null);
    setImportValid(null);
    setImportWords(Array(IMPORT_SLOTS_INITIAL).fill(''));
  }, [mode]);

  const handleCopy = useCallback(async () => {
    try {
      await navigator.clipboard.writeText(mnemonic);
      setCopied(true);
    } catch {
      const textarea = document.createElement('textarea');
      textarea.value = mnemonic;
      textarea.style.position = 'fixed';
      textarea.style.opacity = '0';
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand('copy');
      document.body.removeChild(textarea);
      setCopied(true);
    }
  }, [mnemonic]);

  const handleImportWordChange = useCallback(
    (index: number, value: string) => {
      const pastedWords = value.trim().split(/\s+/).filter(Boolean);
      if (pastedWords.length > 1) {
        const fullPhraseLen = pastedWords.length;
        if (BIP39_IMPORT_LENGTHS.includes(fullPhraseLen as (typeof BIP39_IMPORT_LENGTHS)[number])) {
          setImportWords(pastedWords.map(w => w.toLowerCase()));
          setImportValid(null);
          inputRefs.current[fullPhraseLen - 1]?.focus();
          return;
        }
        const newWords = [...importWords];
        const slotCount = newWords.length;
        for (let i = 0; i < Math.min(pastedWords.length, slotCount - index); i++) {
          newWords[index + i] = pastedWords[i].toLowerCase();
        }
        setImportWords(newWords);
        setImportValid(null);
        const nextEmpty = newWords.findIndex(w => !w);
        const focusIndex = nextEmpty === -1 ? slotCount - 1 : nextEmpty;
        inputRefs.current[focusIndex]?.focus();
        return;
      }

      const newWords = [...importWords];
      newWords[index] = value.toLowerCase().trim();
      setImportWords(newWords);
      setImportValid(null);

      if (value.trim() && index < newWords.length - 1) {
        inputRefs.current[index + 1]?.focus();
      }
    },
    [importWords]
  );

  const handleImportKeyDown = useCallback(
    (index: number, e: KeyboardEvent<HTMLInputElement>) => {
      if (e.key === 'Backspace' && !importWords[index] && index > 0) {
        inputRefs.current[index - 1]?.focus();
      }
    },
    [importWords]
  );

  const handleValidateImport = useCallback(() => {
    const phrase = importWords.join(' ').trim();
    const filledWords = importWords.filter(w => w.trim());
    const n = filledWords.length;

    if (!BIP39_IMPORT_LENGTHS.includes(n as (typeof BIP39_IMPORT_LENGTHS)[number])) {
      setError(`Recovery phrase must be ${BIP39_IMPORT_LENGTHS.join(', ')} words (you have ${n}).`);
      setImportValid(false);
      return false;
    }

    const isValid = validateMnemonicPhrase(phrase);
    setImportValid(isValid);

    if (!isValid) {
      setError('Invalid recovery phrase. Please check your words and try again.');
      return false;
    }

    setError(null);
    return true;
  }, [importWords]);

  const handleContinue = async () => {
    setError(null);
    setLoading(true);

    try {
      let phraseToUse: string;

      if (mode === 'import') {
        if (!handleValidateImport()) {
          setLoading(false);
          return;
        }
        phraseToUse = importWords.join(' ').trim();
      } else {
        if (!confirmed) {
          setLoading(false);
          return;
        }
        phraseToUse = mnemonic;
      }

      if (!user?._id) {
        const msg = 'User not loaded. Please sign in again or refresh the page.';
        setError(msg);
        console.error('[Mnemonic] Cannot save encryption key: user not loaded');
        return;
      }
      await persistLocalWalletFromMnemonic({
        mnemonic: phraseToUse,
        source: mode === 'generate' ? 'generated' : 'imported',
        setEncryptionKey,
      });
      navigate('/home');
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Something went wrong. Please try again.');
    } finally {
      setLoading(false);
    }
  };

  const importWordCount = importWords.filter(w => w.trim()).length;
  const isImportComplete =
    importWords.every(w => w.trim()) &&
    BIP39_IMPORT_LENGTHS.includes(importWordCount as (typeof BIP39_IMPORT_LENGTHS)[number]);
  const canContinue = mode === 'generate' ? confirmed : isImportComplete;

  return (
    <div className="min-h-full flex items-center justify-center p-4 pt-6">
      <div className="max-w-lg w-full">
        <div className="flex justify-center mb-6">
          <LottieAnimation src="/lottie/safe3.json" height={120} width={120} />
        </div>

        <div className="bg-white rounded-2xl shadow-soft border border-stone-200 p-8 animate-fade-up">
          {mode === 'generate' ? (
            <>
              <div className="text-center mb-4">
                <h1 className="text-xl font-bold mb-2">Your Recovery Phrase</h1>
                <p className="opacity-70 text-sm">
                  Write down these {MNEMONIC_GENERATE_WORD_COUNT} words in order and store them
                  somewhere safe. This phrase unlocks your local encryption key and your EVM, BTC,
                  Solana, and Tron wallet identities, and can never be recovered if lost.
                </p>
              </div>

              {/* Mnemonic Grid */}
              <div className="bg-stone-900/5 rounded-2xl p-4 mb-4">
                <div className="grid grid-cols-3 gap-2">
                  {words.map((word, index) => (
                    <div
                      key={index}
                      className="flex items-center gap-2 bg-white/60 rounded-lg px-3 py-2 text-sm">
                      <span className="text-stone-400 font-mono text-xs w-5 text-right">
                        {index + 1}.
                      </span>
                      <span className="font-mono font-medium text-stone-800">{word}</span>
                    </div>
                  ))}
                </div>
              </div>

              {/* Copy Button */}
              <button
                onClick={handleCopy}
                className="w-full flex items-center justify-center gap-2 border border-stone-200 hover:bg-stone-50 text-stone-700 font-medium py-2.5 text-sm rounded-xl transition-all duration-200 mb-3">
                {copied ? (
                  <>
                    <svg
                      className="w-4 h-4 text-sage-500"
                      fill="none"
                      viewBox="0 0 24 24"
                      stroke="currentColor"
                      strokeWidth={2}>
                      <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                    </svg>
                    <span className="text-sage-600">Copied to Clipboard</span>
                  </>
                ) : (
                  <>
                    <svg
                      className="w-4 h-4"
                      fill="none"
                      viewBox="0 0 24 24"
                      stroke="currentColor"
                      strokeWidth={2}>
                      <path
                        strokeLinecap="round"
                        strokeLinejoin="round"
                        d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"
                      />
                    </svg>
                    <span>Copy to Clipboard</span>
                  </>
                )}
              </button>

              {/* Import existing link */}
              <button
                onClick={() => setMode('import')}
                className="w-full text-center text-sm text-primary-500 hover:text-primary-600 transition-colors mb-3">
                I already have a recovery phrase
              </button>

              {/* Confirmation Checkbox */}
              <label className="flex items-start gap-3 cursor-pointer mb-4">
                <input
                  type="checkbox"
                  checked={confirmed}
                  onChange={e => setConfirmed(e.target.checked)}
                  className="mt-0.5 w-4 h-4 rounded border-stone-300 text-primary-500 focus:ring-primary-500"
                />
                <span className="text-sm text-stone-600">
                  I saved this phrase and consent to using it for local wallet setup on this device
                </span>
              </label>
            </>
          ) : (
            <>
              <div className="text-center mb-4">
                <h1 className="text-xl font-bold mb-2">Import Recovery Phrase</h1>
                <p className="opacity-70 text-sm">
                  Enter your recovery phrase below to restore your local encryption key and wallet
                  identities, or paste the full phrase into any field (12 words for new backups;
                  24-word phrases from older versions still work).
                </p>
              </div>

              {/* Import Word Inputs Grid */}
              <div className="bg-stone-900/5 rounded-2xl p-4 mb-4">
                <div className="grid grid-cols-3 gap-2">
                  {importWords.map((word, index) => (
                    <div key={index} className="flex items-center gap-1.5">
                      <span className="text-stone-400 font-mono text-xs w-5 text-right shrink-0">
                        {index + 1}.
                      </span>
                      <input
                        ref={el => {
                          inputRefs.current[index] = el;
                        }}
                        type="text"
                        value={word}
                        onChange={e => handleImportWordChange(index, e.target.value)}
                        onKeyDown={e => handleImportKeyDown(index, e)}
                        autoComplete="off"
                        spellCheck={false}
                        className={`w-full font-mono text-sm font-medium px-2 py-1.5 rounded-lg border bg-white/60 outline-none transition-colors ${
                          importValid === false && word.trim()
                            ? 'border-coral-300 focus:border-coral-400'
                            : importValid === true
                              ? 'border-sage-300 focus:border-sage-400'
                              : 'border-stone-200 focus:border-primary-400'
                        }`}
                      />
                    </div>
                  ))}
                </div>
              </div>

              {/* Validation status */}
              {importValid === true && (
                <div className="flex items-center gap-2 text-sage-600 text-sm mb-3 justify-center">
                  <svg
                    className="w-4 h-4"
                    fill="none"
                    viewBox="0 0 24 24"
                    stroke="currentColor"
                    strokeWidth={2}>
                    <path strokeLinecap="round" strokeLinejoin="round" d="M5 13l4 4L19 7" />
                  </svg>
                  <span>Valid recovery phrase</span>
                </div>
              )}

              {/* Back to generate link */}
              <button
                onClick={() => setMode('generate')}
                className="w-full text-center text-sm text-primary-500 hover:text-primary-600 transition-colors mb-3">
                Generate a new recovery phrase instead
              </button>
            </>
          )}

          {error && <p className="text-coral-500 text-sm mb-3 text-center">{error}</p>}

          {/* Continue Button */}
          <button
            onClick={handleContinue}
            disabled={!canContinue || loading}
            className="w-full flex items-center justify-center space-x-3 bg-blue-500 hover:bg-blue-600 active:bg-blue-700 disabled:opacity-60 disabled:cursor-not-allowed text-white font-semibold py-2.5 text-sm rounded-xl transition-all duration-300 hover:shadow-medium">
            <span>
              {loading
                ? 'Securing Your Data...'
                : mode === 'import'
                  ? 'Import & Continue'
                  : "I'm Ready! Let's Go!"}
            </span>
          </button>
        </div>
      </div>
    </div>
  );
};

export default Mnemonic;
