import { BarChart3, RefreshCw } from "lucide-react";
import SignalPerformanceChart from "./SignalPerformanceChart";
import { useCallback, useEffect, useMemo, useState } from "react";
import type { MarketType } from "@/lib/market";
import type {
    SignalPerformanceBucket,
    SignalPerformanceResponse,
    SignalQualityMatrixCell,
} from "@/types/insight";

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 = {
    symbol: string;
    market: MarketType;
    interval: string;
    enabled: boolean;
    symbols: Record<MarketType, { symbol: string; name: string }[]>;
    intervals: string[];
};

const num = (value: number | null, digits = 2) =>
    value == null ? "—" : value.toFixed(digits);

const streakLabel = (
    val: { type: "win" | "loss" | null; count: number } | null | undefined,
) => {
    if (!val || val.count == null || val.count === 0) return "—";
    if (val.type === "win") return `+${val.count} Win`;
    if (val.type === "loss") return `${val.count} Loss`;
    return `${val.count}`;
};

export default function SignalPerformance({
    symbol,
    market,
    interval,
    enabled,
    symbols,
    intervals,
}: Props) {
    const [data, setData] = useState<SignalPerformanceResponse | null>(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [filterSymbol, setFilterSymbol] = useState(symbol);
    const [filterMarket, setFilterMarket] = useState<MarketType>(market);
    const [filterInterval, setFilterInterval] = useState(interval);
    const [filterDirection, setFilterDirection] = useState<
        "all" | "long" | "short"
    >("all");

    const marketSymbols = useMemo(
        () => symbols[filterMarket] ?? [],
        [filterMarket, symbols],
    );
    const performanceIntervals = useMemo(() => {
        const preferred = ["5m", "15m", "1h", "4h"];
        const available = preferred.filter((value) =>
            intervals.includes(value),
        );
        return available.length > 0 ? available : intervals;
    }, [intervals]);

    useEffect(() => {
        if (!marketSymbols.some((item) => item.symbol === filterSymbol)) {
            setFilterSymbol(marketSymbols[0]?.symbol ?? symbol);
        }
    }, [marketSymbols, filterSymbol, symbol]);

    useEffect(() => {
        setFilterMarket(market);
        setFilterInterval(interval);
        setFilterSymbol(symbol);
    }, [market, interval, symbol]);

    useEffect(() => {
        if (!performanceIntervals.includes(filterInterval)) {
            setFilterInterval(performanceIntervals[0] ?? interval);
        }
    }, [filterInterval, performanceIntervals, interval]);

    const load = useCallback(async () => {
        if (!enabled) return;
        setLoading(true);
        setError(null);
        try {
            const params = new URLSearchParams({
                symbol: filterSymbol,
                market: filterMarket,
                interval: filterInterval,
            });
            if (filterDirection !== "all")
                params.set("direction", filterDirection);
            const response = await fetch(
                `/market/signal-performance?${params.toString()}`,
                {
                    headers: {
                        Accept: "application/json",
                        "X-Requested-With": "XMLHttpRequest",
                    },
                    credentials: "same-origin",
                    cache: "no-store",
                },
            );
            const raw: unknown = await response.json();
            if (!response.ok) {
                const message =
                    raw &&
                    typeof raw === "object" &&
                    "message" in raw &&
                    typeof raw.message === "string"
                        ? raw.message
                        : "Gagal mengambil performance signal.";
                throw new Error(message);
            }
            setData(raw as SignalPerformanceResponse);
        } catch (e) {
            setError(
                e instanceof Error
                    ? e.message
                    : "Gagal mengambil performance signal.",
            );
        } finally {
            setLoading(false);
        }
    }, [enabled, filterDirection, filterInterval, filterMarket, filterSymbol]);

    useEffect(() => {
        void load();
    }, [load]);

    if (!enabled) return null;

    return (
        <Card className="mt-3 border-border bg-card/80 shadow-xs py-4 px-0!">
            <CardHeader className="flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between border-b border-border/60">
                <div className="flex items-center gap-3.5">
                    <div className="flex h-10 w-10 items-center justify-center rounded-xl border border-border bg-muted/40 text-primary">
                        <BarChart3 className="size-5" />
                    </div>
                    <div>
                        <div className="text-[11px] font-semibold uppercase tracking-[.14em] text-muted-foreground">
                            Signal Performance
                        </div>
                        <div className="mt-0.5 text-sm font-semibold text-foreground">
                            {filterSymbol} ·{" "}
                            {filterMarket === "spot" ? "Spot" : "Futures"} ·{" "}
                            {filterInterval}
                        </div>
                    </div>
                </div>

                <div className="flex flex-wrap items-center gap-2">
                    <div className="grid grid-cols-2 sm:grid-cols-4 gap-2">
                        <FilterSelect
                            label="Symbol"
                            value={filterSymbol}
                            onChange={setFilterSymbol}
                            options={marketSymbols.map((item) => ({
                                value: item.symbol,
                                label: item.symbol,
                            }))}
                        />
                        <FilterSelect
                            label="Market"
                            value={filterMarket}
                            onChange={(value) =>
                                setFilterMarket(value as MarketType)
                            }
                            options={[
                                { value: "spot", label: "Spot" },
                                { value: "futures", label: "Futures" },
                            ]}
                        />
                        <FilterSelect
                            label="Timeframe"
                            value={filterInterval}
                            onChange={setFilterInterval}
                            options={performanceIntervals.map((value) => ({
                                value,
                                label: value,
                            }))}
                        />
                        <FilterSelect
                            label="Direction"
                            value={filterDirection}
                            onChange={(value) =>
                                setFilterDirection(
                                    value as "all" | "long" | "short",
                                )
                            }
                            options={[
                                { value: "all", label: "All" },
                                { value: "long", label: "Long / Buy" },
                                { value: "short", label: "Short / Sell" },
                            ]}
                        />
                    </div>
                    <Button
                        type="button"
                        variant="outline"
                        size="sm"
                        onClick={() => void load()}
                        disabled={loading}
                        className="h-9 gap-2 text-xs font-medium shadow-xs mt-auto"
                    >
                        <RefreshCw
                            className={`size-3.5 ${loading ? "animate-spin" : ""}`}
                        />{" "}
                        Refresh
                    </Button>
                </div>
            </CardHeader>

            <CardContent className="p-5 pt-4">
                <DataCardState
                    loading={loading}
                    error={error}
                    hasData={Boolean(data)}
                    onRetry={() => void load()}
                    loadingLabel="Loading signal performance…"
                    empty={Boolean(data && data.summary.total === 0)}
                    emptyLabel="Belum ada performance signal untuk filter ini."
                />

                {data && data.summary.total > 0 && (
                    <div className="space-y-4">
                        <div className="rounded-xl border border-border bg-background/40 p-3.5 shadow-xs">
                            <div className="flex flex-wrap items-center justify-between gap-2">
                                <div>
                                    <div className="text-[10px] font-semibold uppercase tracking-[.14em] text-muted-foreground">
                                        Filtered Performance
                                    </div>
                                    <div className="mt-1 text-xs text-muted-foreground">
                                        {filterSymbol} ·{" "}
                                        {filterMarket === "spot"
                                            ? "Spot"
                                            : "Futures"}{" "}
                                        · {filterInterval} ·{" "}
                                        {filterDirection === "all"
                                            ? "All directions"
                                            : filterDirection === "long"
                                              ? "Long / Buy"
                                              : "Short / Sell"}
                                    </div>
                                </div>
                                <div className="text-[10px] text-muted-foreground">
                                    Comparison tables below use the same active
                                    filters.
                                </div>
                            </div>
                        </div>

                        <div className="grid grid-cols-2 gap-2.5 sm:grid-cols-4 lg:grid-cols-8">
                            <Metric
                                label="Signals"
                                value={data.summary.total.toString()}
                            />
                            <Metric
                                label="Active"
                                value={data.summary.active.toString()}
                            />
                            <Metric
                                label="Wins"
                                value={data.summary.wins.toString()}
                            />
                            <Metric
                                label="Losses"
                                value={data.summary.losses.toString()}
                            />
                            <Metric
                                label="No Trade"
                                value={data.summary.no_trades.toString()}
                            />
                            <Metric
                                label="Entry Rate"
                                value={`${num(data.summary.entry_rate_pct)}%`}
                            />
                            <Metric
                                label="Target Rate"
                                value={`${num(data.summary.target_rate_pct)}%`}
                            />
                            <Metric
                                label="Average R"
                                value={
                                    data.summary.average_r == null
                                        ? "—"
                                        : `${data.summary.average_r > 0 ? "+" : ""}${num(data.summary.average_r)}R`
                                }
                            />
                        </div>

                        <div className="grid gap-3 lg:grid-cols-[minmax(0,2fr)_minmax(260px,1fr)]">
                            <SignalPerformanceChart
                                points={data.equity_curve}
                            />
                            <div className="rounded-xl border border-border bg-background/40 p-4 shadow-xs">
                                <div className="text-[10px] font-semibold uppercase tracking-[.14em] text-muted-foreground">
                                    Risk Profile
                                </div>
                                <div className="mt-3 space-y-2.5 text-xs">
                                    <StatRow
                                        label="Max Drawdown"
                                        value={
                                            data.summary.max_drawdown_r == null
                                                ? "—"
                                                : `${data.summary.max_drawdown_r.toFixed(2)}R`
                                        }
                                    />
                                    <StatRow
                                        label="Current Streak"
                                        value={streakLabel(
                                            data.summary.current_streak,
                                        )}
                                    />
                                    <StatRow
                                        label="Best Win Streak"
                                        value={`${data.summary.best_win_streak}`}
                                    />
                                    <StatRow
                                        label="Worst Loss Streak"
                                        value={`${data.summary.worst_loss_streak}`}
                                    />
                                </div>
                            </div>
                        </div>

                        <div className="grid gap-3 lg:grid-cols-3">
                            <BucketList
                                title="By Timeframe"
                                items={data.by_timeframe}
                            />
                            <BucketList
                                title="By Market"
                                items={data.by_market}
                            />
                            <BucketList
                                title="By Direction"
                                items={data.by_direction}
                            />
                        </div>

                        <div className="rounded-xl border border-border bg-background/40 p-4 shadow-xs space-y-3">
                            <div className="flex flex-wrap items-start justify-between gap-2">
                                <div>
                                    <div className="text-[10px] font-semibold uppercase tracking-[.14em] text-muted-foreground">
                                        Performance by Signal Quality
                                    </div>
                                    <div className="mt-1 text-xs text-muted-foreground">
                                        Confidence and confirmation alignment
                                        are measured from the signal snapshot at
                                        detection time.
                                    </div>
                                </div>
                                <div className="text-[10px] text-muted-foreground">
                                    Quality coverage:{" "}
                                    {data.quality_coverage.with_confidence}/
                                    {data.quality_coverage.total} confidence ·{" "}
                                    {
                                        data.quality_coverage
                                            .with_confirmation_alignment
                                    }
                                    /{data.quality_coverage.total} confirmation
                                </div>
                            </div>

                            <div className="grid gap-3 lg:grid-cols-2">
                                <QualityBucketList
                                    title="By Confidence"
                                    items={data.by_confidence}
                                />
                                <QualityBucketList
                                    title="By Confirmation Alignment"
                                    items={data.by_confirmation_alignment}
                                />
                            </div>
                        </div>

                        <SignalQualityMatrix cells={data.quality_matrix} />

                        <div className="rounded-xl border border-border bg-background/40 p-3.5 text-[11px] text-muted-foreground shadow-xs">
                            Total R:{" "}
                            {data.summary.total_r == null
                                ? "—"
                                : `${data.summary.total_r > 0 ? "+" : ""}${num(data.summary.total_r)}R`}
                            . Invalidated before entry are counted as{" "}
                            <strong className="font-semibold text-foreground">
                                No Trade
                            </strong>
                            , not as losses.
                        </div>
                    </div>
                )}
            </CardContent>
        </Card>
    );
}

function FilterSelect({
    label,
    value,
    onChange,
    options,
}: {
    label: string;
    value: string;
    onChange: (value: string) => void;
    options: { value: string; label: string }[];
}) {
    return (
        <label className="min-w-0 block">
            <span className="mb-1 block text-[9px] font-semibold uppercase tracking-wide text-muted-foreground">
                {label}
            </span>
            <Select value={value} onValueChange={onChange}>
                <SelectTrigger className="h-8 w-full text-xs font-medium shadow-xs">
                    <SelectValue />
                </SelectTrigger>
                <SelectContent>
                    {options.map((option) => (
                        <SelectItem key={option.value} value={option.value}>
                            {option.label}
                        </SelectItem>
                    ))}
                </SelectContent>
            </Select>
        </label>
    );
}

function Metric({ label, value }: { label: string; value: string }) {
    return (
        <div className="rounded-xl border border-border bg-background p-3 shadow-xs">
            <div className="text-[10px] uppercase tracking-wide text-muted-foreground">
                {label}
            </div>
            <div className="mt-1 text-sm font-bold text-foreground">
                {value}
            </div>
        </div>
    );
}

function StatRow({ label, value }: { label: string; value: string }) {
    return (
        <div className="flex items-center justify-between">
            <span className="text-muted-foreground">{label}</span>
            <span className="font-semibold text-foreground">{value}</span>
        </div>
    );
}

function BucketList({
    title,
    items,
}: {
    title: string;
    items: SignalPerformanceBucket[];
}) {
    return (
        <div className="rounded-xl border border-border bg-background/40 p-4 shadow-xs">
            <div className="text-[10px] font-semibold uppercase tracking-[.14em] text-muted-foreground">
                {title}
            </div>
            <div className="mt-3 space-y-2.5">
                {items.length === 0 ? (
                    <div className="text-xs text-muted-foreground">—</div>
                ) : (
                    items.map((item) => (
                        <div
                            key={item.key}
                            className="flex items-center gap-2 text-xs"
                        >
                            <span className="min-w-0 flex-1 truncate font-semibold text-foreground">
                                {item.key}
                            </span>
                            <span className="text-muted-foreground">
                                {item.wins}W / {item.losses}L
                            </span>
                            <span className="font-semibold text-foreground">
                                {item.average_r == null
                                    ? "—"
                                    : `${item.average_r > 0 ? "+" : ""}${num(item.average_r)}R`}
                            </span>
                        </div>
                    ))
                )}
            </div>
        </div>
    );
}

function QualityBucketList({
    title,
    items,
}: {
    title: string;
    items: SignalPerformanceBucket[];
}) {
    return (
        <div className="rounded-xl border border-border/70 bg-background/30 p-3.5 shadow-xs">
            <div className="text-[10px] font-semibold uppercase tracking-[.12em] text-muted-foreground">
                {title}
            </div>
            <div className="mt-2.5 space-y-2">
                {items.length === 0 ? (
                    <div className="text-xs text-muted-foreground">
                        No quality data yet.
                    </div>
                ) : (
                    items.map((item) => (
                        <div
                            key={item.key}
                            className="grid grid-cols-[minmax(0,1fr)_auto_auto_auto] items-center gap-2 text-xs"
                        >
                            <span className="min-w-0 truncate font-semibold text-foreground">
                                {item.key}
                            </span>
                            <span className="text-muted-foreground">
                                {item.total}
                            </span>
                            <span className="text-muted-foreground">
                                {item.wins}W / {item.losses}L
                            </span>
                            <span className="font-semibold text-foreground">
                                {item.average_r == null
                                    ? "—"
                                    : `${item.average_r > 0 ? "+" : ""}${num(item.average_r)}R`}
                            </span>
                        </div>
                    ))
                )}
            </div>
            <div className="mt-2 text-[9px] text-muted-foreground">
                Total · W/L · Average R
            </div>
        </div>
    );
}

function SignalQualityMatrix({ cells }: { cells: SignalQualityMatrixCell[] }) {
    const confidenceRows = [
        "<50%",
        "50–59%",
        "60–69%",
        "70–79%",
        "80–89%",
        "90–100%",
    ];
    const alignmentColumns = [
        "Opposed (0–39)",
        "Mixed (40–59)",
        "Aligned (60–79)",
        "Strongly aligned (80–100)",
    ];

    const lookup = new Map(
        cells.map((cell) => [
            `${cell.confidence_bucket}|${cell.alignment_bucket}`,
            cell,
        ]),
    );

    return (
        <div className="rounded-xl border border-border bg-background/40 p-4 shadow-xs space-y-3">
            <div className="flex flex-wrap items-start justify-between gap-2">
                <div>
                    <div className="text-[10px] font-semibold uppercase tracking-[.14em] text-muted-foreground">
                        Signal Quality Matrix
                    </div>
                    <div className="mt-1 text-xs text-muted-foreground">
                        Confidence × confirmation alignment. Only signals with
                        both quality snapshots are included.
                    </div>
                </div>
                <div className="text-[10px] text-muted-foreground">
                    Cell: signals · W/L · average R
                </div>
            </div>

            <div className="overflow-x-auto rounded-xl border border-border shadow-xs">
                <table className="w-full min-w-[760px] border-collapse text-xs">
                    <thead className="bg-muted/40">
                        <tr>
                            <th className="border-b border-border px-3 py-2.5 text-left font-semibold text-muted-foreground">
                                Confidence
                            </th>
                            {alignmentColumns.map((column) => (
                                <th
                                    key={column}
                                    className="border-b border-border px-3 py-2.5 text-left font-semibold text-muted-foreground"
                                >
                                    {column}
                                </th>
                            ))}
                        </tr>
                    </thead>
                    <tbody>
                        {confidenceRows.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 text-foreground">
                                    {row}
                                </td>
                                {alignmentColumns.map((column) => {
                                    const cell = lookup.get(`${row}|${column}`);

                                    return (
                                        <td
                                            key={column}
                                            className="px-3 py-2.5 align-top"
                                        >
                                            {cell ? (
                                                <div className="rounded-lg border border-border/70 bg-background p-2.5 shadow-xs">
                                                    <div className="font-semibold text-foreground">
                                                        {cell.total} signal
                                                        {cell.total === 1
                                                            ? ""
                                                            : "s"}
                                                    </div>
                                                    <div className="mt-0.5 text-muted-foreground">
                                                        {cell.wins}W /{" "}
                                                        {cell.losses}L
                                                        {cell.no_trades > 0
                                                            ? ` · ${cell.no_trades} NT`
                                                            : ""}
                                                    </div>
                                                    <div className="mt-0.5 font-semibold text-foreground">
                                                        {cell.average_r == null
                                                            ? "—"
                                                            : `${
                                                                  cell.average_r >
                                                                  0
                                                                      ? "+"
                                                                      : ""
                                                              }${num(cell.average_r)}R`}
                                                    </div>
                                                </div>
                                            ) : (
                                                <div className="rounded-lg border border-dashed border-border/60 p-2.5 text-muted-foreground text-center">
                                                    —
                                                </div>
                                            )}
                                        </td>
                                    );
                                })}
                            </tr>
                        ))}
                    </tbody>
                </table>
            </div>
        </div>
    );
}
