import React, { useMemo, useState } from "react";
import { Globe, Copy, ExternalLink, CheckCircle2, AlertCircle, X, Eye, EyeOff, Info } from "lucide-react";
import { InteractionEntropy } from "../lib/interactionEntropy";
import { entropyToMnemonic } from "../lib/seedblend";

type RandomOrgStats = {
    source: "randomorg";
    nRequested: number;
    nUsed: number;
    distribution: number[]; // counts for faces 1..6
    interactionSamples: number;
    totalBits: number;
};

interface RandomOrgEntropyProps {
    wordCount: 12 | 24;
    onEntropyGenerated: (mnemonic: string, stats: RandomOrgStats) => void;
    onCancel: () => void;
    interactionEntropy: InteractionEntropy;
}

function buildRequest(apiKey: string, n: number) {
    return {
        jsonrpc: "2.0",
        method: "generateIntegers",
        params: { apiKey, n, min: 1, max: 6, replacement: true, base: 10 },
        id: 1,
    };
}

function parseD6FromPaste(text: string): number[] {
    const t = text.trim();
    if (!t) throw new Error("Paste the random.org response JSON (or an array) first.");

    // Allow direct array paste: [1,6,2,...]
    if (t.startsWith("[") && t.endsWith("]")) {
        const arr = JSON.parse(t);
        if (!Array.isArray(arr)) throw new Error("Expected an array.");
        return arr;
    }

    const obj = JSON.parse(t);
    const data = obj?.result?.random?.data;
    if (!Array.isArray(data)) throw new Error("Could not find result.random.data in pasted JSON.");
    return data;
}

async function mnemonicFromD6(
    d6: number[],
    wordCount: 12 | 24,
    interactionEntropy: InteractionEntropy
): Promise<string> {
    const interactionBytes = await interactionEntropy.getEntropyBytes();
    const cryptoBytes = crypto.getRandomValues(new Uint8Array(32));

    // Keep it simple + consistent with your other sources: concatenate strings, SHA-256, slice entropy.
    const combined = [
        d6.join(""),
        performance.now().toString(),
        Array.from(interactionBytes).join(","),
        Array.from(cryptoBytes).join(","),
    ].join("|");

    const data = new TextEncoder().encode(combined);
    const hash = await crypto.subtle.digest("SHA-256", data);

    const entropyLength = wordCount === 12 ? 16 : 32;
    const finalEntropy = new Uint8Array(hash.slice(0, entropyLength));

    return entropyToMnemonic(finalEntropy);
}

const RandomOrgEntropy: React.FC<RandomOrgEntropyProps> = ({
    wordCount,
    onEntropyGenerated,
    onCancel,
    interactionEntropy,
}) => {
    const [apiKey, setApiKey] = useState("");
    const [showKey, setShowKey] = useState(false);

    const [n, setN] = useState(30); // min 30
    const [paste, setPaste] = useState("");

    const [error, setError] = useState<string>("");
    const [copied, setCopied] = useState(false);

    const [processing, setProcessing] = useState(false);
    const [stats, setStats] = useState<RandomOrgStats | null>(null);
    const [generatedMnemonic, setGeneratedMnemonic] = useState("");

    const requestJson = useMemo(() => {
        const key = apiKey.trim() || "PASTE_YOUR_API_KEY_HERE";
        return JSON.stringify(buildRequest(key, n), null, 2);
    }, [apiKey, n]);

    const copyRequest = async () => {
        setError("");
        try {
            await navigator.clipboard.writeText(requestJson);
            setCopied(true);
            window.setTimeout(() => setCopied(false), 1200);
        } catch {
            setError("Clipboard write failed. Tap the JSON box to select all, then copy manually.");
        }
    };

    const generate = async () => {
        setError("");
        setProcessing(true);
        try {
            const raw = parseD6FromPaste(paste);

            if (raw.length < n) throw new Error(`Need at least ${n} D6 samples, got ${raw.length}.`);

            const d6 = raw.slice(0, n);
            const dist = [0, 0, 0, 0, 0, 0];
            for (let i = 0; i < d6.length; i++) {
                const v = d6[i];
                if (!Number.isInteger(v) || v < 1 || v > 6) throw new Error(`Invalid D6 at index ${i}: ${String(v)}`);
                dist[v - 1]++;
            }

            const mnemonic = await mnemonicFromD6(d6, wordCount, interactionEntropy);

            setGeneratedMnemonic(mnemonic);
            setStats({
                source: "randomorg",
                nRequested: n,
                nUsed: d6.length,
                distribution: dist,
                interactionSamples: interactionEntropy.getSampleCount().total,
                totalBits: 256,
            });
        } catch (e) {
            setStats(null);
            setGeneratedMnemonic("");
            setError(e instanceof Error ? e.message : "Failed.");
        } finally {
            setProcessing(false);
        }
    };

    return (
        <div className="space-y-4 max-h-[calc(100vh-200px)] overflow-y-auto">
            {!stats && !processing && (
                <>
                    <div className="p-3 md:p-4 bg-[#16213e] rounded-xl border-2 border-[#00f0ff]/30 space-y-3">
                        <div className="flex items-center gap-2">
                            <Globe size={20} className="text-[#00f0ff]" />
                            <h3 className="text-sm font-bold text-[#00f0ff] uppercase">🌍 Random.org Entropy</h3>
                        </div>

                        <div className="flex items-start gap-2 text-xs text-[#6ef3f7]">
                            <Info size={14} className="shrink-0 mt-0.5 text-[#00f0ff]" />
                            <p>
                                SeedPGP will not contact random.org. You run the request in another tab/tool and paste the response here.
                            </p>
                        </div>
                    </div>

                    <div className="space-y-1">
                        <label className="text-[10px] font-bold text-[#00f0ff] uppercase tracking-widest">random.org API key</label>
                        <div className="relative">
                            <input
                                type={showKey ? "text" : "password"}
                                value={apiKey}
                                onChange={(e) => setApiKey(e.target.value)}
                                placeholder="Paste API key (optional; not stored)"
                                className="w-full pl-3 pr-10 py-2 bg-[#16213e] border-2 border-[#00f0ff]/50 rounded-lg text-[#00f0ff] text-xs placeholder-[#9d84b7] focus:outline-none focus:border-[#ff006e] transition-all"
                                autoCapitalize="none"
                                autoCorrect="off"
                                spellCheck={false}
                            />
                            <button
                                type="button"
                                className="absolute right-2 top-2 text-[#6ef3f7] hover:text-[#00f0ff]"
                                onClick={() => setShowKey((s) => !s)}
                            >
                                {showKey ? <EyeOff size={16} /> : <Eye size={16} />}
                            </button>
                        </div>
                    </div>

                    <div className="space-y-2">
                        <div className="flex items-center justify-between">
                            <label className="text-[10px] font-bold text-[#00f0ff] uppercase tracking-widest">D6 samples</label>
                            <span className="text-xs text-[#00f0ff] font-mono">{n}</span>
                        </div>
                        <input
                            type="range"
                            min={30}
                            max={200}
                            step={10}
                            value={n}
                            onChange={(e) => setN(parseInt(e.target.value, 10))}
                            className="w-full accent-[#ff006e]"
                        />
                        <p className="text-[10px] text-[#6ef3f7]">Minimum 30. Step 10.</p>
                    </div>

                    <div className="space-y-2">
                        <div className="flex items-center justify-between gap-2">
                            <label className="text-[10px] font-bold text-[#00f0ff] uppercase tracking-widest">Request JSON</label>
                            <div className="flex gap-2">
                                <a
                                    href="https://api.random.org/json-rpc/2/request-builder"
                                    target="_blank"
                                    rel="noreferrer"
                                    className="inline-flex items-center gap-1 px-2 py-1 rounded-lg border-2 border-[#00f0ff]/50 text-[#00f0ff] text-[10px] hover:bg-[#00f0ff]/10 transition-all"
                                >
                                    <ExternalLink size={12} />
                                    Request Builder
                                </a>
                                <button
                                    type="button"
                                    onClick={copyRequest}
                                    className="inline-flex items-center gap-1 px-2 py-1 rounded-lg border-2 border-[#00f0ff]/50 text-[#00f0ff] text-[10px] hover:bg-[#00f0ff]/10 transition-all"
                                >
                                    <Copy size={12} />
                                    {copied ? "Copied" : "Copy"}
                                </button>
                            </div>
                        </div>
                        <textarea
                            readOnly
                            value={requestJson}
                            onFocus={(e) => e.currentTarget.select()}
                            className="w-full h-28 md:h-36 p-2 md:p-3 bg-[#0a0a0f] border-2 border-[#00f0ff]/50 rounded-lg font-mono text-[10px] text-[#00f0ff] focus:outline-none"
                        />
                        <p className="text-[10px] text-[#6ef3f7]">
                            Endpoint: <span className="font-mono text-[#00f0ff]">https://api.random.org/json-rpc/1/invoke</span>
                        </p>
                    </div>

                    <div className="space-y-2">
                        <label className="text-[10px] font-bold text-[#00f0ff] uppercase tracking-widest">Paste response JSON</label>
                        <textarea
                            value={paste}
                            onChange={(e) => setPaste(e.target.value)}
                            placeholder="Paste JSON-RPC response, or paste a [1,6,2,...] array"
                            className="w-full h-28 md:h-36 p-2 md:p-3 bg-[#16213e] border-2 border-[#00f0ff]/50 rounded-lg font-mono text-[10px] text-[#00f0ff] placeholder-[#9d84b7] focus:outline-none focus:border-[#ff006e] transition-all"
                        />
                    </div>

                    {error && (
                        <div className="flex items-start gap-2 p-3 bg-[#0a0a0f] border border-[#ff006e] rounded-lg">
                            <AlertCircle size={16} className="text-[#ff006e] shrink-0 mt-0.5" />
                            <p className="text-xs text-[#ff006e]">{error}</p>
                        </div>
                    )}

                    <div className="flex gap-3">
                        <button
                            onClick={generate}
                            className="flex-1 py-2.5 bg-gradient-to-r from-[#ff006e] to-[#ff4d8f] text-white text-sm rounded-lg font-bold uppercase hover:shadow-[0_0_20px_rgba(255,0,110,0.5)] transition-all"
                        >
                            Generate Seed
                        </button>
                        <button
                            onClick={onCancel}
                            className="px-4 py-2.5 bg-[#16213e] border-2 border-[#ff006e] text-[#ff006e] rounded-lg font-bold text-sm hover:bg-[#ff006e]/20 transition-all"
                        >
                            <X size={16} />
                        </button>
                    </div>
                </>
            )}

            {processing && (
                <div className="p-6 bg-[#16213e] rounded-xl border-2 border-[#00f0ff]/30 text-center space-y-3">
                    <div className="animate-spin mx-auto w-12 h-12 border-4 border-[#00f0ff]/30 border-t-[#00f0ff] rounded-full" />
                    <p className="text-sm text-[#00f0ff]">Processing entropy...</p>
                </div>
            )}

            {stats && !processing && (
                <div className="p-6 bg-[#16213e] rounded-xl border-2 border-[#39ff14] shadow-[0_0_30px_rgba(57,255,20,0.3)] space-y-4 mb-6">
                    <div className="flex items-center gap-2 text-[#39ff14]">
                        <CheckCircle2 size={24} />
                        <h3 className="text-sm font-bold uppercase">Random.org Entropy Analysis</h3>
                    </div>

                    <div className="space-y-3 text-xs">
                        <div>
                            <p className="text-[#00f0ff] font-bold mb-1">Primary Source</p>
                            <p className="text-[#6ef3f7]">random.org D6 integers (pasted manually)</p>
                        </div>

                        <div>
                            <p className="text-[#00f0ff] font-bold mb-2">SAMPLES</p>
                            <div className="grid grid-cols-2 gap-2 font-mono text-[10px]">
                                <div>Requested</div><div className="text-[#39ff14]">{stats.nRequested}</div>
                                <div>Used</div><div className="text-[#39ff14]">{stats.nUsed}</div>
                                <div>Interaction samples</div><div className="text-[#39ff14]">{stats.interactionSamples}</div>
                            </div>
                        </div>

                        <div>
                            <p className="text-[#00f0ff] font-bold mb-2">DISTRIBUTION</p>
                            <div className="space-y-1 font-mono text-[10px]">
                                {stats.distribution.map((count, i) => {
                                    const pct = (count / stats.nUsed) * 100;
                                    return (
                                        <div key={i} className="flex justify-between">
                                            <span>Face {i + 1}</span>
                                            <span className="text-[#39ff14]">{count} ({pct.toFixed(1)}%)</span>
                                        </div>
                                    );
                                })}
                            </div>
                        </div>

                        <div>
                            <p className="text-[#00f0ff] font-bold mb-2">GENERATED SEED</p>
                            <div className="p-3 bg-[#0a0a0f] rounded-lg border border-[#39ff14]/50">
                                <p className="font-mono text-[10px] text-[#39ff14] blur-sensitive" title="Hover to reveal">
                                    {generatedMnemonic}
                                </p>
                                <p className="text-[9px] text-[#6ef3f7] mt-1">👆 Hover to reveal - Write this down securely</p>
                            </div>
                        </div>

                        <div>
                            <p className="text-[#00f0ff] font-bold mb-2">MIXED WITH</p>
                            <div className="space-y-1 text-[10px] text-[#6ef3f7]">
                                <div>- crypto.getRandomValues() ✓</div>
                                <div>- performance.now() ✓</div>
                                <div>- Interaction timing ({stats.interactionSamples} samples) ✓</div>
                            </div>
                        </div>

                        <div className="pt-2 border-t border-[#00f0ff]/30">
                            <div className="flex justify-between items-center">
                                <span className="text-[#00f0ff] font-bold">Total Entropy</span>
                                <span className="text-lg font-bold text-[#39ff14]">{stats.totalBits} bits</span>
                            </div>
                        </div>
                    </div>

                    <div className="pt-4 border-t border-[#00f0ff]/30 space-y-3">
                        <button
                            onClick={() => onEntropyGenerated(generatedMnemonic, stats)}
                            className="w-full py-3 bg-gradient-to-r from-[#ff006e] to-[#ff4d8f] text-white text-sm rounded-xl font-bold uppercase hover:shadow-[0_0_30px_rgba(255,0,110,0.8)] transition-all"
                        >
                            Continue with this Seed
                        </button>

                        <button
                            onClick={() => {
                                setStats(null);
                                setGeneratedMnemonic("");
                                setPaste("");
                                setError("");
                            }}
                            className="w-full py-2 bg-[#16213e] border-2 border-[#00f0ff] text-[#00f0ff] rounded-lg text-sm font-bold hover:bg-[#00f0ff]/20 transition-all"
                        >
                            Paste a different response
                        </button>
                    </div>
                </div>
            )}
        </div>
    );
};

export default RandomOrgEntropy;
