/**
 * @file SeedBlender.tsx
 * @summary Main component for the Seed Blending feature.
 * @description This component provides a full UI for the multi-step seed blending process,
 * handling various input formats, per-row decryption, and final output actions.
 */
import { useState, useEffect, useCallback, useRef } from 'react';
import { QrCode, X, Plus, CheckCircle2, AlertTriangle, RefreshCw, Sparkles, EyeOff, Lock, Key, ArrowRight } from 'lucide-react';
import QRScanner from './QRScanner';
import { decryptFromSeed, detectEncryptionMode } from '../lib/seedpgp';
import { decryptFromKrux } from '../lib/krux';
import { decodeSeedQR } from '../lib/seedqr'; // New import
import { QrDisplay } from './QrDisplay';
import {
    blendMnemonicsAsync,
    checkXorStrength,
    mnemonicToEntropy,
    DiceStats,
    calculateDiceStats,
    detectBadPatterns,
    diceToBytes,
    hkdfExtractExpand,
    entropyToMnemonic,
    mixWithDiceAsync,
} from '../lib/seedblend';

function debounce<F extends (...args: any[]) => any>(func: F, waitFor: number) {
    let timeout: ReturnType<typeof setTimeout> | null = null;
    return (...args: Parameters<F>): void => {
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(() => func(...args), waitFor);
    };
}

interface MnemonicEntry {
    id: number;
    rawInput: string;
    decryptedMnemonic: string | null;
    isEncrypted: boolean;
    inputType: 'text' | 'seedpgp' | 'krux' | 'seedqr';
    passwordRequired: boolean;
    passwordInput: string;
    error: string | null;
    isValid: boolean | null;
}

let nextId = 0;
const createNewEntry = (): MnemonicEntry => ({
    id: nextId++, rawInput: '', decryptedMnemonic: null, isEncrypted: false,
    inputType: 'text', passwordRequired: false, passwordInput: '', error: null, isValid: null,
});

interface SeedBlenderProps {
    onDirtyStateChange: (isDirty: boolean) => void;
    setMnemonicForBackup: (mnemonic: string) => void;
    requestTabChange: (tab: 'create' | 'backup' | 'restore' | 'seedblender') => void;
    incomingSeed?: string; // NEW: seed from Create tab
    onSeedReceived?: () => void; // NEW: callback after seed added
}

export function SeedBlender({ onDirtyStateChange, setMnemonicForBackup, requestTabChange, incomingSeed, onSeedReceived }: SeedBlenderProps) {
    const processedSeedsRef = useRef<Set<string>>(new Set());
    const [entries, setEntries] = useState<MnemonicEntry[]>([createNewEntry()]);
    const [showQRScanner, setShowQRScanner] = useState(false);
    const [scanTargetIndex, setScanTargetIndex] = useState<number | null>(null);
    const [blendedResult, setBlendedResult] = useState<{ blendedEntropy: Uint8Array; blendedMnemonic12: string; blendedMnemonic24?: string; } | null>(null);
    const [xorStrength, setXorStrength] = useState<{ isWeak: boolean; uniqueBytes: number; } | null>(null);
    const [blendError, setBlendError] = useState<string>('');
    const [blending, setBlending] = useState(false);
    const [diceRolls, setDiceRolls] = useState('');
    const [diceStats, setDiceStats] = useState<DiceStats | null>(null);
    const [dicePatternWarning, setDicePatternWarning] = useState<string | null>(null);
    const [diceOnlyMnemonic, setDiceOnlyMnemonic] = useState<string | null>(null);
    const [finalMnemonic, setFinalMnemonic] = useState<string | null>(null);
    const [mixing, setMixing] = useState(false);
    const [showFinalQR, setShowFinalQR] = useState(false);

    useEffect(() => {
        const isDirty = entries.some(e => e.rawInput.length > 0) || diceRolls.length > 0;
        onDirtyStateChange(isDirty);
    }, [entries, diceRolls, onDirtyStateChange]);

    const addSeedEntry = (seed: string) => {
        setEntries(currentEntries => {
            const emptyEntryIndex = currentEntries.findIndex(e => !e.rawInput.trim());
            if (emptyEntryIndex !== -1) {
                return currentEntries.map((entry, index) =>
                    index === emptyEntryIndex
                        ? { ...entry, rawInput: seed, decryptedMnemonic: seed, isValid: null, error: null }
                        : entry
                );
            } else {
                const newEntry = createNewEntry();
                newEntry.rawInput = seed;
                newEntry.decryptedMnemonic = seed;
                return [...currentEntries, newEntry];
            }
        });
    };

    useEffect(() => {
        if (incomingSeed && incomingSeed.trim()) {
            // Check if we've already processed this exact seed
            if (!processedSeedsRef.current.has(incomingSeed)) {
                const isDuplicate = entries.some(e => e.decryptedMnemonic === incomingSeed);
                if (!isDuplicate) {
                    addSeedEntry(incomingSeed);
                    processedSeedsRef.current.add(incomingSeed);
                }
            }
            // Always notify parent to clear the incoming seed
            onSeedReceived?.();
        }
    }, [incomingSeed]);

    const handleLockAndClear = () => {
        setEntries([createNewEntry()]);
        setBlendedResult(null);
        setXorStrength(null);
        setBlendError('');
        setDiceRolls('');
        setDiceStats(null);
        setDicePatternWarning(null);
        setDiceOnlyMnemonic(null);
        setFinalMnemonic(null);
        setShowFinalQR(false);
    };

    useEffect(() => {
        const processEntries = async () => {
            setBlending(true);
            setBlendError('');
            const validMnemonics = entries.map(e => e.decryptedMnemonic).filter((m): m is string => m !== null && m.length > 0);

            const validityPromises = entries.map(async (entry) => {
                if (!entry.rawInput.trim()) return { isValid: null, error: null };
                if (entry.isEncrypted && !entry.decryptedMnemonic) return { isValid: null, error: null };

                const textToValidate = entry.decryptedMnemonic || entry.rawInput;
                try {
                    await mnemonicToEntropy(textToValidate.trim());
                    return { isValid: true, error: null };
                } catch (e: any) {
                    return { isValid: false, error: e.message || "Invalid mnemonic" };
                }
            });
            const newValidationResults = await Promise.all(validityPromises);
            setEntries(currentEntries => currentEntries.map((e, i) => ({
                ...e,
                isValid: newValidationResults[i]?.isValid ?? e.isValid,
                error: newValidationResults[i]?.error ?? e.error,
            })));

            if (validMnemonics.length > 0) {
                try {
                    const result = await blendMnemonicsAsync(validMnemonics);
                    setBlendedResult(result);
                    setXorStrength(checkXorStrength(result.blendedEntropy));
                } catch (e: any) { setBlendError(e.message); setBlendedResult(null); }
            } else {
                setBlendedResult(null);
            }
            setBlending(false);
        };
        debounce(processEntries, 300)();
    }, [JSON.stringify(entries.map(e => e.decryptedMnemonic))]);

    useEffect(() => {
        const processDice = async () => {
            setDiceStats(calculateDiceStats(diceRolls));
            setDicePatternWarning(detectBadPatterns(diceRolls).message || null);
            if (diceRolls.length >= 50) {
                try {
                    const outputByteLength = (blendedResult && blendedResult.blendedEntropy.length >= 32) ? 32 : 16;
                    const diceOnlyEntropy = await hkdfExtractExpand(diceToBytes(diceRolls), outputByteLength, new TextEncoder().encode('dice-only'));
                    setDiceOnlyMnemonic(await entropyToMnemonic(diceOnlyEntropy));
                } catch { setDiceOnlyMnemonic(null); }
            } else { setDiceOnlyMnemonic(null); }
        };
        debounce(processDice, 200)();
    }, [diceRolls, blendedResult]);

    const updateEntry = (index: number, newProps: Partial<MnemonicEntry>) => {
        setEntries(currentEntries => currentEntries.map((entry, i) => i === index ? { ...entry, ...newProps } : entry));
    };
    const handleAddEntry = () => setEntries([...entries, createNewEntry()]);
    const handleRemoveEntry = (id: number) => {
        if (entries.length > 1) setEntries(entries.filter(e => e.id !== id));
        else setEntries([createNewEntry()]);
    };

    const handleScan = (index: number) => {
        setScanTargetIndex(index);
        setShowQRScanner(true);
    };

    const handleScanSuccess = useCallback(async (scannedData: string | Uint8Array) => {
        if (scanTargetIndex === null) return;

        const scannedText = typeof scannedData === 'string'
            ? scannedData
            : Array.from(scannedData).map(b => b.toString(16).padStart(2, '0')).join('');

        const mode = detectEncryptionMode(scannedText);
        let mnemonic = scannedText;
        let error: string | null = null;
        let inputType: 'text' | 'seedpgp' | 'krux' | 'seedqr' = 'text';

        try {
            if (mode === 'seedqr') {
                mnemonic = await decodeSeedQR(scannedText);
                inputType = 'seedqr';
                updateEntry(scanTargetIndex, {
                    rawInput: mnemonic,
                    decryptedMnemonic: mnemonic,
                    isEncrypted: false,
                    passwordRequired: false,
                    inputType,
                    error: null,
                });
            } else if (mode === 'pgp' || mode === 'krux') {
                inputType = (mode === 'pgp' ? 'seedpgp' : mode);
                updateEntry(scanTargetIndex, {
                    rawInput: scannedText,
                    decryptedMnemonic: null,
                    isEncrypted: true,
                    passwordRequired: true,
                    inputType,
                    error: null,
                });
            } else { // text or un-recognized
                updateEntry(scanTargetIndex, {
                    rawInput: scannedText,
                    decryptedMnemonic: scannedText,
                    isEncrypted: false,
                    passwordRequired: false,
                    inputType: 'text',
                    error: null,
                });
            }
        } catch (e: any) {
            error = e.message || "Failed to process QR code";
            updateEntry(scanTargetIndex, { rawInput: scannedText, error });
        }
        setShowQRScanner(false);
    }, [scanTargetIndex]);

    const handleScanClose = useCallback(() => {
        setShowQRScanner(false);
    }, []);

    const handleScanError = useCallback((errMsg: string) => {
        if (scanTargetIndex !== null) {
            updateEntry(scanTargetIndex, { error: errMsg });
        }
    }, [scanTargetIndex]);

    const handleDecrypt = async (index: number) => {
        const entry = entries[index];
        if (!entry.isEncrypted || !entry.passwordInput) return;
        try {
            let mnemonic: string;
            if (entry.inputType === 'krux') {
                mnemonic = (await decryptFromKrux({ kefData: entry.rawInput, passphrase: entry.passwordInput })).mnemonic;
            } else { // seedpgp
                mnemonic = (await decryptFromSeed({ frameText: entry.rawInput, messagePassword: entry.passwordInput, mode: 'pgp' })).w;
            }
            updateEntry(index, { rawInput: mnemonic, decryptedMnemonic: mnemonic, isEncrypted: false, passwordRequired: false, error: null });
        } catch (e: any) {
            updateEntry(index, { error: e.message || "Decryption failed" });
        }
    };

    const handleFinalMix = async () => {
        if (!blendedResult) return;
        setMixing(true);
        try {
            const outputBits = blendedResult.blendedEntropy.length >= 32 ? 256 : 128;
            const result = await mixWithDiceAsync(blendedResult.blendedEntropy, diceRolls, outputBits);
            setFinalMnemonic(result.finalMnemonic);
        } catch (e) { setFinalMnemonic(null); } finally { setMixing(false); }
    };

    const handleTransfer = () => {
        if (!finalMnemonic) return;
        // Set mnemonic for backup
        setMnemonicForBackup(finalMnemonic);
        // Switch to backup tab
        requestTabChange('backup');
        // DON'T auto-clear - user can use "Reset All" button if they want to start fresh
        // This preserves the blended seed in case user wants to come back and export QR
    };

    const getBorderColor = (isValid: boolean | null) => {
        if (isValid === true) return 'border-[#39ff14] focus:ring-[#39ff14]';
        if (isValid === false) return 'border-[#ff006e] focus:ring-[#ff006e]';
        return 'border-[#00f0ff]/50 focus:ring-[#00f0ff]';
    };

    return (
        <>
            <div className="space-y-6 pb-20">
                <div className="mb-6">
                    <h2 className="text-lg font-bold text-[#00f0ff] uppercase tracking-widest" style={{ textShadow: '0 0 10px rgba(0,240,255,0.7)' }}>
                        Seed Blender
                    </h2>
                </div>

                <div className="p-6 bg-[#16213e] rounded-xl border-2 border-[#00f0ff]/30">
                    <h3 className="font-semibold text-lg mb-4 text-[#00f0ff]" style={{ textShadow: '0 0 10px rgba(0,240,255,0.7)' }}>Step 1: Input Mnemonics</h3>
                    <div className="space-y-4">
                        {entries.map((entry, index) => (
                            <div key={entry.id} className="p-3 bg-[#1a1a2e] rounded-lg border-2 border-[#00f0ff]/20">
                                {entry.passwordRequired ? (
                                    <div className="space-y-2">
                                        <div className="flex items-center justify-between"><label className="text-sm font-semibold text-[#00f0ff]">Decrypt {entry.inputType.toUpperCase()} Mnemonic</label><button onClick={() => updateEntry(index, createNewEntry())} className="text-xs text-[#6ef3f7] hover:text-[#00f0ff]">&times; Cancel</button></div>
                                        <p className="text-xs text-[#6ef3f7] truncate">Payload: <code className="text-[#9d84b7]">{entry.rawInput.substring(0, 40)}...</code></p>
                                        <div className="flex gap-2"><input type="password" placeholder="Enter passphrase to decrypt..." value={entry.passwordInput} onChange={(e) => updateEntry(index, { passwordInput: e.target.value })} className="w-full p-2 bg-[#16213e] border-2 border-[#00f0ff]/50 rounded-lg text-sm font-mono text-[#00f0ff] placeholder-[#9d84b7] focus:outline-none focus:border-[#ff006e] focus:shadow-[0_0_20px_rgba(255,0,110,0.5)]" /><button onClick={() => handleDecrypt(index)} className="px-4 bg-[#ff006e] text-white rounded-lg font-semibold hover:bg-[#ff4d8f] hover:shadow-[0_0_15px_rgba(255,0,110,0.5)]"><Key size={16} /></button></div>
                                        {entry.error && <p className="text-xs text-[#ff006e]">{entry.error}</p>}
                                    </div>
                                ) : (
                                    <div className="space-y-2">
                                        {/* Row 1: Textarea only */}
                                        <textarea
                                            value={entry.rawInput}
                                            onChange={(e) => updateEntry(index, { rawInput: e.target.value, decryptedMnemonic: e.target.value, isValid: null, error: null })}
                                            placeholder={`Mnemonic #${index + 1} (12 or 24 words)`}
                                            className={`w-full h-24 p-3 bg-[#0a0a0f] border-2 rounded-lg font-mono text-xs placeholder:text-[10px] placeholder:text-[#6ef3f7] focus:outline-none focus:border-[#ff006e] focus:shadow-[0_0_20px_rgba(255,0,110,0.5)] transition-all ${getBorderColor(entry.isValid)}`}
                                        />
                                        {/* Row 2: QR button (left) and X button (right) */}
                                        <div className="flex items-center justify-between">
                                            <button
                                                onClick={() => handleScan(index)}
                                                className="flex items-center gap-1.5 px-3 py-1.5 bg-[#16213e] border border-[#00f0ff] text-[#00f0ff] text-xs rounded-lg hover:bg-[#00f0ff20] transition-all"
                                                title="Scan QR code"
                                            >
                                                <QrCode size={14} />
                                                <span>Scan QR</span>
                                            </button>

                                            <button
                                                onClick={() => handleRemoveEntry(entry.id)}
                                                className="p-1.5 bg-[#16213e] border border-[#ff006e] text-[#ff006e] rounded-lg hover:bg-[#ff006e20] transition-all"
                                                title="Remove mnemonic"
                                            >
                                                <X size={14} />
                                            </button>
                                        </div>
                                        {entry.error && <p className="text-xs text-[#ff006e] px-1">{entry.error}</p>}
                                    </div>
                                )}
                            </div>
                        ))}
                        <button onClick={handleAddEntry} className="w-full py-2.5 bg-[#1a1a2e] hover:bg-[#16213e] text-[#00f0ff] rounded-lg font-semibold flex items-center justify-center gap-2 border-2 border-[#00f0ff]/50"><Plus size={16} /> Add Another Mnemonic</button>
                    </div>
                </div>

                <div className="p-6 bg-[#16213e] rounded-xl border-2 border-[#00f0ff]/30 min-h-[10rem]">
                    <h3 className="font-semibold text-lg mb-4 text-[#00f0ff]" style={{ textShadow: '0 0 10px rgba(0,240,255,0.7)' }}>Step 2: Blended Preview</h3>
                    {blending ? <p className="text-sm text-[#6ef3f7]">Blending...</p> : !blendError && blendedResult ? (<div className="space-y-4 animate-in fade-in">{xorStrength?.isWeak && (<div className="p-3 bg-[#ff006e]/10 border-2 border-[#ff006e]/30 text-[#ff006e] rounded-lg text-sm flex gap-3"><AlertTriangle /><div><span className="font-bold">Weak XOR Result:</span> Detected only {xorStrength.uniqueBytes} unique bytes. This can happen if seeds are identical or too similar.</div></div>)}<div className="space-y-1"><label className="text-xs font-semibold text-[#00f0ff] uppercase tracking-widest" style={{ textShadow: '0 0 10px rgba(0,240,255,0.7)' }}>Blended Mnemonic (12-word)</label><p data-sensitive="Blended Mnemonic (12-word)" className="p-3 bg-[#1a1a2e] rounded-md font-mono text-sm text-[#00f0ff] break-words border-2 border-[#00f0ff]/30">{blendedResult.blendedMnemonic12}</p></div>{blendedResult.blendedMnemonic24 && (<div className="space-y-1"><label className="text-xs font-semibold text-[#00f0ff] uppercase tracking-widest" style={{ textShadow: '0 0 10px rgba(0,240,255,0.7)' }}>Blended Mnemonic (24-word)</label><p data-sensitive="Blended Mnemonic (24-word)" className="p-3 bg-[#1a1a2e] rounded-md font-mono text-sm text-[#00f0ff] break-words border-2 border-[#00f0ff]/30">{blendedResult.blendedMnemonic24}</p></div>)}</div>) : (<p className="text-sm text-[#6ef3f7]">{blendError || 'Previews will appear here once you enter one or more valid mnemonics.'}</p>)}
                </div>

                <div className="p-6 bg-[#16213e] rounded-xl border-2 border-[#00f0ff]/30">
                    <h3 className="font-semibold text-lg mb-4 text-[#00f0ff]" style={{ textShadow: '0 0 10px rgba(0,240,255,0.7)' }}>Step 3: Input Dice Rolls</h3>
                    <div className="space-y-4">
                        <textarea value={diceRolls} onChange={(e) => setDiceRolls(e.target.value.replace(/[^1-6]/g, ''))} placeholder="99+ dice rolls (e.g., 16345...)" className="w-full h-32 p-3 bg-[#16213e] border-2 border-[#00f0ff]/50 rounded-lg font-mono text-xs placeholder:text-[10px] placeholder:text-[#6ef3f7]" />
                        {dicePatternWarning && (<div className="p-3 bg-[#ff006e]/10 border-2 border-[#ff006e]/30 text-[#ff006e] rounded-lg text-sm flex gap-3"><AlertTriangle /><p><span className="font-bold">Warning:</span> {dicePatternWarning}</p></div>)}
                        {diceStats && diceStats.length > 0 && (<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-center"><div className="p-3 bg-[#1a1a2e] rounded-lg border-2 border-[#00f0ff]/30"><p className="text-xs text-[#6ef3f7]">Rolls</p><p className="text-lg font-bold text-[#00f0ff]">{diceStats.length}</p></div><div className="p-3 bg-[#1a1a2e] rounded-lg border-2 border-[#00f0ff]/30"><p className="text-xs text-[#6ef3f7]">Entropy (bits)</p><p className="text-lg font-bold text-[#00f0ff]">{diceStats.estimatedEntropyBits.toFixed(1)}</p></div><div className="p-3 bg-[#1a1a2e] rounded-lg border-2 border-[#00f0ff]/30"><p className="text-xs text-[#6ef3f7]">Mean</p><p className="text-lg font-bold text-[#00f0ff]">{diceStats.mean.toFixed(2)}</p></div><div className="p-3 bg-[#1a1a2e] rounded-lg border-2 border-[#00f0ff]/30"><p className="text-xs text-[#6ef3f7]">Chi-Square</p><p className={`text-lg font-bold ${diceStats.chiSquare > 11.07 ? 'text-[#ff006e]' : 'text-[#00f0ff]'}`}>{diceStats.chiSquare.toFixed(2)}</p></div></div>)}
                        {diceOnlyMnemonic && (<div className="space-y-1 pt-2"><label className="text-xs font-semibold text-[#00f0ff] uppercase tracking-widest" style={{ textShadow: '0 0 10px rgba(0,240,255,0.7)' }}>Dice-Only Preview Mnemonic</label><p data-sensitive="Dice-Only Preview Mnemonic" className="p-3 bg-[#1a1a2e] rounded-md font-mono text-sm text-[#00f0ff] break-words border-2 border-[#00f0ff]/30">{diceOnlyMnemonic}</p></div>)}
                    </div>
                </div>

                <div className="p-6 bg-[#16213e] rounded-xl border-2 border-[#00f0ff]/50 shadow-[0_0_20px_rgba(0,240,255,0.3)]">
                    <h3 className="font-semibold text-lg mb-4 text-[#00f0ff]" style={{ textShadow: '0 0 10px rgba(0,240,255,0.7)' }}>Step 4: Generate Final Mnemonic</h3>
                    {finalMnemonic ? (
                        <div className="p-4 bg-[#0a0a0f] border-2 border-[#39ff14] rounded-2xl shadow-[0_0_20px_rgba(57,255,20,0.3)]">
                            <div className="flex items-center justify-between mb-4"><span className="font-bold text-[#39ff14] flex items-center gap-2 text-lg" style={{ textShadow: '0 0 10px rgba(57,255,20,0.8)' }}><CheckCircle2 size={22} /> Final Mnemonic Generated</span><button onClick={() => setFinalMnemonic(null)} className="p-2.5 hover:bg-[#16213e] rounded-xl transition-all text-[#39ff14] hover:shadow-[0_0_15px_rgba(57,255,20,0.5)] flex items-center gap-2"><EyeOff size={22} /> Hide</button></div>
                            <div className="p-6 bg-[#0a0a0f] rounded-xl border-2 border-[#39ff14] shadow-[0_0_20px_rgba(57,255,20,0.3)]"><p data-sensitive="Final Blended Mnemonic" className="font-mono text-center text-lg break-words text-[#39ff14]">{finalMnemonic}</p></div>
                            <div className="mt-4 p-3 bg-[#ff006e]/10 text-[#ff006e] rounded-lg text-xs flex gap-2 border-2 border-[#ff006e]/30"><AlertTriangle size={16} className="shrink-0 mt-0.5" /><span><strong>Security Warning:</strong> Write this down immediately. Do not save it digitally.</span></div>
                            <div className="grid grid-cols-2 gap-3 mt-4">
                                <button onClick={() => setShowFinalQR(true)} className="w-full py-2.5 bg-[#1a1a2e] text-[#00f0ff] rounded-lg font-semibold flex items-center justify-center gap-2 border-2 border-[#00f0ff]/50 hover:bg-[#16213e] hover:shadow-[0_0_15px_rgba(0,240,255,0.3)]"><QrCode size={16} /> Export as QR</button>
                                <button
                                    onClick={handleTransfer}
                                    className="w-full py-2.5 bg-gradient-to-r from-[#ff006e] to-[#ff4d8f] text-white rounded-lg font-bold uppercase tracking-wider flex items-center justify-center gap-2 hover:shadow-[0_0_30px_rgba(255,0,110,0.8)] active:scale-95 transition-all disabled:opacity-50 disabled:cursor-not-allowed border border-[#ff006e]"
                                    style={{ textShadow: '0 0 10px rgba(255,255,255,0.8)' }}
                                    disabled={!finalMnemonic}
                                >
                                    <ArrowRight size={20} />
                                    Send to Backup Tab
                                </button>
                            </div>
                        </div>
                    ) : (
                        <><p className="text-sm text-[#6ef3f7] mb-4">Once you have entered valid mnemonics and at least 50 dice rolls, you can generate the final mnemonic.</p><button onClick={handleFinalMix} disabled={!blendedResult || !diceRolls || diceRolls.length < 50 || mixing} className="w-full py-3 bg-gradient-to-r from-[#00f0ff] to-[#0066ff] text-[#16213e] rounded-xl font-bold flex items-center justify-center gap-2 disabled:opacity-50 hover:shadow-[0_0_20px_rgba(0,240,255,0.5)]">{mixing ? <RefreshCw className="animate-spin" size={20} /> : <Sparkles size={20} />}{mixing ? 'Generating...' : 'Mix Mnemonic + Dice'}</button></>
                    )}
                </div>
            </div>

            {showQRScanner && <QRScanner
                onScanSuccess={handleScanSuccess}
                onClose={handleScanClose}
                onError={handleScanError}
            />}
            {showFinalQR && finalMnemonic && (
                <div className="fixed inset-0 bg-black/60 z-50 flex items-center justify-center" onClick={() => setShowFinalQR(false)}>
                    <div className="bg-[#16213e] rounded-2xl p-4 border-2 border-[#00f0ff]/50" onClick={e => e.stopPropagation()}>
                        <QrDisplay value={finalMnemonic} />
                    </div>
                </div>
            )}
        </>
    );
}
