import { useI18n } from "@/lib/i18n";
import { useEffect, useMemo, useRef, useState } from "react";
import { RefreshCw, GitCompare } from "lucide-react";
import type { MarketType } from "@/lib/market";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { DataCardState } from "./DataCardState";
import { Button } from "@/components/ui/button";
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/components/ui/select";

type Props = {
    market: MarketType;
    interval: string;
    provider?: string;
};

type ResponseData = {
    market: "futures";
    provider?: string;
    interval: string;
    window: number;
    as_of: number | null;
    symbols: string[];
    sample_counts: Record<string, number>;
    matrix: Record<string, Record<string, number | null>>;
};

const fmt = (value: number | null | undefined) =>
    value == null ? "—" : value.toFixed(2);

const level = (value: number | null | undefined) => {
    if (value == null) return "Insufficient";
    const a = Math.abs(value);
    if (a >= 0.8) return "Very High";
    if (a >= 0.6) return "High";
    if (a >= 0.4) return "Moderate";
    if (a >= 0.2) return "Low";
    return "Very Low";
};

export default function CorrelationPanel({ market, interval, provider = "binance" }: Props) {
    const { t } = useI18n();
    const [windowSize, setWindowSize] = useState(100);
    const [data, setData] = useState<ResponseData | null>(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const requestRef = useRef<AbortController | null>(null);
    const contextRef = useRef(`${market}|${interval}|${provider}`);

    const enabled = market === "futures";

    const load = async () => {
        if (!enabled) return;
        requestRef.current?.abort();
        const controller = new AbortController();
        requestRef.current = controller;
        const requestContext = `${market}|${interval}|${provider}`;
        setLoading(true);
        setError(null);

        try {
            const params = new URLSearchParams({
                market: "futures",
                provider,
                interval,
                window: String(windowSize),
            });

            // Laravel validates `symbols` as an array, so the query must use
            // the PHP/Laravel array notation instead of a comma-separated
            // string (`symbols=BTCUSDT,ETHUSDT,SOLUSDT`).
            ["BTCUSDT", "ETHUSDT", "SOLUSDT"].forEach((symbol) => {
                params.append("symbols[]", symbol);
            });

            const response = await fetch(
                `/market/correlation?${params.toString()}`,
                {
                    headers: {
                        Accept: "application/json",
                        "X-Requested-With": "XMLHttpRequest",
                    },
                    credentials: "same-origin",
                    cache: "no-store",
                    signal: controller.signal,
                },
            );

            const raw = (await response
                .json()
                .catch(() => ({}))) as ResponseData & { message?: string };
            if (!response.ok)
                throw new Error(
                    raw.message ||
                        `Correlation request failed: ${response.status}`,
                );

            if (!controller.signal.aborted && contextRef.current === requestContext) setData(raw);
        } catch (caught) {
            if (controller.signal.aborted || contextRef.current !== requestContext) return;
            setError(
                caught instanceof Error
                    ? caught.message
                    : "Gagal menghitung correlation.",
            );
        } finally {
            if (contextRef.current === requestContext) setLoading(false);
            if (requestRef.current === controller) requestRef.current = null;
        }
    };

    useEffect(() => {
        const context = `${market}|${interval}|${provider}`;
        contextRef.current = context;
        requestRef.current?.abort();
        setData(null);
        setError(null);
        setLoading(false);
        void load();
        return () => requestRef.current?.abort();
    }, [enabled, interval, windowSize, provider]);

    const pairs = useMemo(() => {
        if (!data) return [];
        const pairs: { a: string; b: string; value: number | null }[] = [];
        for (let i = 0; i < data.symbols.length; i++) {
            for (let j = i + 1; j < data.symbols.length; j++) {
                const a = data.symbols[i];
                const b = data.symbols[j];
                pairs.push({ a, b, value: data.matrix[a]?.[b] ?? null });
            }
        }
        return pairs;
    }, [data]);

    if (!enabled) return null;

    return (
        <Card className="mt-3 border-border bg-card/80 shadow-xs py-4 px-0!">
            <CardHeader className="flex flex-row items-center justify-between border-b border-border/60">
                <div className="flex items-center gap-3">
                    <div className="flex h-10 w-10 items-center justify-center rounded-xl border border-border bg-muted/40 text-primary">
                        <GitCompare className="size-5" />
                    </div>
                    <div>
                        <div className="text-[11px] font-semibold uppercase tracking-[.14em] text-muted-foreground">
                            {t("Correlation Matrix")}
                        </div>
                        <div className="mt-0.5 text-sm font-semibold text-foreground">
                            {provider.toUpperCase()} · BTC · ETH · SOL · Futures · {interval}
                        </div>
                    </div>
                </div>

                <div className="flex items-center gap-2">
                    <Select
                        value={String(windowSize)}
                        onValueChange={(val) => setWindowSize(Number(val))}
                    >
                        <SelectTrigger className="h-9 w-[130px] text-xs font-medium shadow-xs">
                            <SelectValue />
                        </SelectTrigger>
                        <SelectContent>
                            {[30, 60, 100, 200, 500].map((value) => (
                                <SelectItem key={value} value={String(value)}>
                                    {value} candles
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>

                    <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={() => void load()}
                        disabled={loading}
                        className="h-9 gap-2 text-xs font-medium shadow-xs"
                    >
                        <RefreshCw
                            className={`size-3.5 ${loading ? "animate-spin" : ""}`}
                        />
                        {t("Refresh")}
                    </Button>
                </div>
            </CardHeader>

            <CardContent className="p-5 pt-4">
                <DataCardState
                    loading={loading}
                    error={error}
                    hasData={Boolean(data)}
                    onRetry={() => void load()}
                    loadingLabel={t("Calculating correlation…")}
                    empty={!loading && !error && !data}
                    emptyLabel={t(
                        "Correlation data belum tersedia. Coba refresh untuk menghitung ulang.",
                    )}
                />

                {data && (
                    <div className="space-y-4">
                        <div className="overflow-x-auto rounded-xl border border-border shadow-xs">
                            <table className="w-full min-w-[420px] text-xs">
                                <thead>
                                    <tr className="border-b border-border bg-muted/40 text-muted-foreground">
                                        <th className="px-3 py-2.5 text-left">
                                            {t("Asset")}
                                        </th>
                                        {data.symbols.map((symbol) => (
                                            <th
                                                key={symbol}
                                                className="px-3 py-2.5 text-right font-semibold"
                                            >
                                                {symbol.replace("USDT", "")}
                                            </th>
                                        ))}
                                    </tr>
                                </thead>
                                <tbody>
                                    {data.symbols.map((row) => (
                                        <tr
                                            key={row}
                                            className="border-b border-border/60 last:border-0 hover:bg-muted/20"
                                        >
                                            <td className="px-3 py-2.5 font-semibold">
                                                {row}
                                            </td>
                                            {data.symbols.map((col) => (
                                                <td
                                                    key={col}
                                                    className="px-3 py-2.5 text-right tabular-nums"
                                                >
                                                    {fmt(
                                                        data.matrix[row]?.[col],
                                                    )}
                                                </td>
                                            ))}
                                        </tr>
                                    ))}
                                </tbody>
                            </table>
                        </div>

                        <div className="grid gap-3 sm:grid-cols-3">
                            {pairs.map((pair) => (
                                <div
                                    key={`${pair.a}-${pair.b}`}
                                    className="rounded-xl border border-border bg-background p-3.5 shadow-xs"
                                >
                                    <div className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                                        {pair.a.replace("USDT", "")} ↔{" "}
                                        {pair.b.replace("USDT", "")}
                                    </div>
                                    <div className="mt-1 flex items-baseline justify-between">
                                        <span className="text-lg font-bold tabular-nums">
                                            {fmt(pair.value)}
                                        </span>
                                        <span className="text-[10px] font-medium text-muted-foreground">
                                            {level(pair.value)}
                                        </span>
                                    </div>
                                </div>
                            ))}
                        </div>

                        <div className="text-[11px] leading-4 text-muted-foreground">
                            Correlation dihitung dari return candle pada market,
                            timeframe, dan window yang dipilih. Nilai ini
                            menggambarkan hubungan historis, bukan rekomendasi
                            membuka atau menutup posisi.
                        </div>
                    </div>
                )}
            </CardContent>
        </Card>
    );
}
