import React, { useEffect, useMemo, useRef, useState } from "react";
import { Button, Select, TextInput, useToast } from "../admin/ui";

type LeaderboardPayload = any;

export function LeaderboardChristmasPage() {
    const { toast } = useToast();
    const [sessionKey, setSessionKey] = useState<string>("");
    const [charId, setCharId] = useState<string>("173793");
    const [intervalMs, setIntervalMs] = useState<string>("5000");
    const [upstreamUrl, setUpstreamUrl] = useState<string>("");
    const [running, setRunning] = useState(false);
    const [logs, setLogs] = useState<string[]>([]);
    const [data, setData] = useState<LeaderboardPayload | null>(null);
    const esRef = useRef<EventSource | null>(null);
    const bottomRef = useRef<HTMLDivElement>(null);

    const canStart = useMemo(() => {
        return sessionKey.trim() !== "" && /^\d+$/.test(charId.trim());
    }, [sessionKey, charId]);

    useEffect(() => {
        bottomRef.current?.scrollIntoView({ behavior: "smooth" });
    }, [logs]);

    const log = (msg: string) => setLogs((p) => [...p, msg]);

    const start = () => {
        if (running || !canStart) return;
        setRunning(true);
        setData(null);
        setLogs([]);
        const qs = new URLSearchParams();
        qs.set("session_key", sessionKey.trim());
        qs.set("char_id", charId.trim());
        if (intervalMs.trim() !== "") qs.set("interval_ms", intervalMs.trim());
        if (upstreamUrl.trim() !== "") qs.set("url", upstreamUrl.trim());
        const url = `/leaderboard/christmas/stream?${qs.toString()}`;
        const es = new EventSource(url);
        esRef.current = es;
        log("Menghubungkan stream leaderboard...");
        es.addEventListener("meta", (e: any) => {
            log(`[META] ${e.data}`);
        });
        es.addEventListener("leaderboard", (e: any) => {
            log(`[LEADERBOARD] paket diterima`);
            try {
                const d = JSON.parse(e.data);
                setData(d);
            } catch {
                setData(e.data);
            }
        });
        es.addEventListener("error", (e: any) => {
            try {
                const d = JSON.parse(e.data);
                log(`[ERROR] ${d.error || "error"} ${d.message ? "- " + d.message : ""}`);
            } catch {
                log(`[ERROR] Stream error atau koneksi ditutup.`);
            }
            toast("error", "Stream error.");
            stop();
        });
        es.onerror = () => {
            log("[ERROR] Koneksi stream gagal atau ditutup.");
            toast("error", "Stream terputus.");
            stop();
        };
    };

    const stop = () => {
        if (esRef.current) {
            try {
                esRef.current.close();
            } catch {}
            esRef.current = null;
        }
        setRunning(false);
    };

    const renderTable = () => {
        const anyData = data as any;
        const rows: any[] =
            (Array.isArray(anyData?.list) && anyData.list) ||
            (Array.isArray(anyData?.leaders) && anyData.leaders) ||
            (Array.isArray(anyData) && anyData) ||
            [];
        if (!Array.isArray(rows) || rows.length === 0) {
            return (
                <div className="rounded-lg border border-white/10 bg-white/[0.02] p-4 text-sm text-gray-300">
                    Tidak ada data tabel. Lihat JSON di bawah.
                </div>
            );
        }
        const cols = Object.keys(rows[0] || {});
        return (
            <div className="overflow-x-auto rounded-lg border border-white/10">
                <table className="min-w-full divide-y divide-white/10 text-sm">
                    <thead className="bg-white/[0.02]">
                        <tr>
                            {cols.map((c) => (
                                <th key={c} className="px-3 py-2 text-left font-semibold text-gray-200">{c}</th>
                            ))}
                        </tr>
                    </thead>
                    <tbody className="divide-y divide-white/5">
                        {rows.slice(0, 50).map((row, i) => (
                            <tr key={i} className="hover:bg-white/[0.03]">
                                {cols.map((c) => (
                                    <td key={c} className="px-3 py-2 text-gray-300">{String(row?.[c] ?? "")}</td>
                                ))}
                            </tr>
                        ))}
                    </tbody>
                </table>
            </div>
        );
    };

    return (
        <div className="space-y-6">
            <div className="grid gap-4 md:grid-cols-2">
                <TextInput label="Session Key" value={sessionKey} onChange={(e) => setSessionKey((e.target as any).value)} />
                <TextInput label="Char ID" value={charId} onChange={(e) => setCharId((e.target as any).value)} />
                <Select
                    label="Interval"
                    value={intervalMs}
                    onChange={(e) => setIntervalMs((e.target as any).value)}
                >
                    <option value="2000">2s</option>
                    <option value="5000">5s</option>
                    <option value="10000">10s</option>
                </Select>
                <TextInput label="Upstream URL (opsional)" value={upstreamUrl} onChange={(e) => setUpstreamUrl((e.target as any).value)} />
            </div>
            <div className="flex flex-wrap gap-2">
                <Button onClick={start} disabled={!canStart || running}>
                    Mulai Stream
                </Button>
                <Button onClick={stop} variant="secondary" disabled={!running}>
                    Hentikan
                </Button>
            </div>
            <div className="h-40 overflow-y-auto rounded bg-black/50 p-3 font-mono text-xs text-green-400">
                {logs.join("\n")}
                <div ref={bottomRef} />
            </div>
            {data && (
                <div className="space-y-4">
                    {renderTable()}
                    <div className="rounded-lg border border-white/10 bg-white/[0.02] p-4">
                        <div className="text-xs font-semibold text-gray-400">Raw JSON</div>
                        <pre className="mt-2 max-h-[420px] overflow-auto text-xs text-gray-300">{JSON.stringify(data, null, 2)}</pre>
                    </div>
                </div>
            )}
        </div>
    );
}
