import { useEffect, useMemo, useRef, useState, type ReactNode } from "react";
import { useI18n } from "@/lib/i18n";
import type { MarketType } from "@/lib/market";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Badge } from "@/components/ui/badge";
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from "@/components/ui/select";
import type { BacktestResult } from "../../lib/backtest-types";

interface BacktestPanelProps {
    symbol: string;
    market: MarketType;
    interval: string;
    provider?: string;
    onResult?: (result: BacktestResult | null) => void;
    onSelectTrade?: (index: number | null) => void;
}

const money = (value: number) =>
    value.toLocaleString("en-US", { maximumFractionDigits: 2 });

const pct = (value: number) => `${value >= 0 ? "+" : ""}${value.toFixed(2)}%`;

export default function BacktestPanel({
    symbol,
    market,
    interval,
    provider = "binance",
    onResult,
    onSelectTrade,
}: BacktestPanelProps) {
    const { t } = useI18n();
    const [strategy, setStrategy] = useState("ema_cross");
    const [direction, setDirection] = useState("both");
    const [capital, setCapital] = useState("10000");
    const [sl, setSl] = useState("2");
    const [tp, setTp] = useState("4");
    const [fee, setFee] = useState("0.1");
    const [slippage, setSlippage] = useState("0.05");
    const [risk, setRisk] = useState("1");
    const [leverage, setLeverage] = useState("1");
    const [marginMode, setMarginMode] = useState<"isolated" | "cross">(
        "isolated",
    );
    const [maintenanceRate, setMaintenanceRate] = useState("0.5");
    const [candles, setCandles] = useState("500");
    const [fast, setFast] = useState("20");
    const [slow, setSlow] = useState("50");
    const [ambiguity, setAmbiguity] = useState("conservative");
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [result, setResult] = useState<BacktestResult | null>(null);
    const [selectedTrade, setSelectedTrade] = useState<number | null>(null);
    const requestRef = useRef<AbortController | null>(null);
    const requestGenerationRef = useRef(0);
    const effectiveDirection = market === "spot" ? "long" : direction;

    useEffect(() => {
        requestRef.current?.abort();
        requestRef.current = null;
        requestGenerationRef.current += 1;
        setLoading(false);
        setError(null);
        setResult(null);
        setSelectedTrade(null);
        onResult?.(null);
        onSelectTrade?.(null);

        return () => {
            requestRef.current?.abort();
            requestRef.current = null;
        };
    }, [symbol, market, interval, provider]);

    useEffect(() => {
        if (market === "spot" && direction !== "long") {
            setDirection("long");
        }
    }, [market, direction]);

    const maxEquity = useMemo(
        () => Math.max(...(result?.equity_curve.map((x) => x.equity) ?? [1])),
        [result],
    );

    const selectTrade = (index: number) => {
        setSelectedTrade((current) => {
            const next = current === index ? null : index;
            onSelectTrade?.(next);
            return next;
        });
    };

    const run = async () => {
        requestRef.current?.abort();
        const controller = new AbortController();
        requestRef.current = controller;
        const generation = ++requestGenerationRef.current;

        setLoading(true);
        setError(null);
        setSelectedTrade(null);
        onSelectTrade?.(null);

        try {
            const response = await fetch("/market/backtest", {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                    Accept: "application/json",
                    "X-Requested-With": "XMLHttpRequest",
                    "X-CSRF-TOKEN":
                        document
                            .querySelector('meta[name="csrf-token"]')
                            ?.getAttribute("content") ?? "",
                },
                credentials: "same-origin",
                signal: controller.signal,
                body: JSON.stringify({
                    symbol,
                    market,
                    provider,
                    interval,
                    strategy,
                    direction: effectiveDirection,
                    capital: Number(capital),
                    stop_loss_pct: Number(sl),
                    take_profit_pct: Number(tp),
                    fee_pct: Number(fee),
                    slippage_pct: Number(slippage),
                    risk_pct: Number(risk),
                    leverage: market === "futures" ? Number(leverage) : 1,
                    margin_mode: market === "futures" ? marginMode : "cash",
                    maintenance_margin_rate:
                        market === "futures"
                            ? Number(maintenanceRate) / 100
                            : 0,
                    candles_limit: Number(candles),
                    ambiguity,
                    fast_period: Number(fast),
                    slow_period: Number(slow),
                }),
            });

            const payload = await response.json().catch(() => ({}));

            if (!response.ok) {
                throw new Error(
                    payload?.message ??
                        (response.status === 402
                            ? t(
                                  "backtest.pro_required",
                                  "Backtest requires Pro access.",
                              )
                            : t("backtest.failed", "Backtest failed to run.")),
                );
            }

            if (
                generation !== requestGenerationRef.current ||
                controller.signal.aborted
            ) {
                return;
            }

            const nextResult = payload as BacktestResult;
            setResult(nextResult);
            onResult?.(nextResult);
        } catch (e) {
            if (
                controller.signal.aborted ||
                generation !== requestGenerationRef.current
            ) {
                return;
            }

            const message =
                e instanceof Error
                    ? e.message
                    : t("backtest.failed", "Backtest failed to run.");

            setError(message);
            setResult(null);
            onResult?.(null);
        } finally {
            if (generation === requestGenerationRef.current) {
                setLoading(false);
                if (requestRef.current === controller) {
                    requestRef.current = null;
                }
            }
        }
    };

    return (
        <Card className="mt-4 border-border bg-card shadow-xs">
            <CardHeader className="flex flex-row items-start justify-between border-b border-border/60 pb-4 p-5">
                <div>
                    <div className="text-[11px] font-bold uppercase tracking-[.16em] text-emerald-500">
                        {t("backtest.title", "Backtest Engine")}
                    </div>
                    <p className="mt-1 text-xs text-muted-foreground">
                        {t(
                            "backtest.subtitle",
                            "Simulate entry → SL/TP → exit → fee → slippage → funding → PnL.",
                        )}
                    </p>
                </div>
                <Badge
                    variant="outline"
                    className="border-emerald-500/20 bg-emerald-500/10 text-[10px] font-semibold text-emerald-600 dark:text-emerald-300"
                >
                    PRO
                </Badge>
            </CardHeader>

            <CardContent className="p-5 pt-4 space-y-4">
                <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
                    <Field label={t("backtest.strategy", "Strategy")}>
                        <Select value={strategy} onValueChange={setStrategy}>
                            <SelectTrigger className="h-9 text-xs shadow-xs">
                                <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="ema_cross">
                                    EMA Cross
                                </SelectItem>
                                <SelectItem value="rsi_reversion">
                                    RSI Reversion
                                </SelectItem>
                            </SelectContent>
                        </Select>
                    </Field>

                    <Field label={t("backtest.direction", "Direction")}>
                        <Select value={effectiveDirection} onValueChange={setDirection}>
                            <SelectTrigger className="h-9 text-xs shadow-xs">
                                <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="long">Long only</SelectItem>
                                {market === "futures" ? (
                                    <>
                                        <SelectItem value="both">
                                            Long + Short
                                        </SelectItem>
                                        <SelectItem value="short">
                                            Short only
                                        </SelectItem>
                                    </>
                                ) : null}
                            </SelectContent>
                        </Select>
                    </Field>

                    <Field label={t("backtest.capital", "Initial capital")}>
                        <Input
                            type="number"
                            min="10"
                            value={capital}
                            onChange={(e) => setCapital(e.target.value)}
                            className="h-9 text-xs shadow-xs"
                        />
                    </Field>

                    <Field label={t("backtest.candles", "Historical candles")}>
                        <Select value={candles} onValueChange={setCandles}>
                            <SelectTrigger className="h-9 text-xs shadow-xs">
                                <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="250">250</SelectItem>
                                <SelectItem value="500">500</SelectItem>
                                <SelectItem value="1000">1000</SelectItem>
                            </SelectContent>
                        </Select>
                    </Field>

                    <Field label="Stop Loss %">
                        <Input
                            type="number"
                            step="0.05"
                            value={sl}
                            onChange={(e) => setSl(e.target.value)}
                            className="h-9 text-xs shadow-xs"
                        />
                    </Field>

                    <Field label="Take Profit %">
                        <Input
                            type="number"
                            step="0.05"
                            value={tp}
                            onChange={(e) => setTp(e.target.value)}
                            className="h-9 text-xs shadow-xs"
                        />
                    </Field>

                    <Field label="Fee % / side">
                        <Input
                            type="number"
                            step="0.01"
                            value={fee}
                            onChange={(e) => setFee(e.target.value)}
                            className="h-9 text-xs shadow-xs"
                        />
                    </Field>

                    <Field label="Slippage %">
                        <Input
                            type="number"
                            step="0.01"
                            value={slippage}
                            onChange={(e) => setSlippage(e.target.value)}
                            className="h-9 text-xs shadow-xs"
                        />
                    </Field>

                    <Field label="Risk / trade %">
                        <Input
                            type="number"
                            step="0.1"
                            value={risk}
                            onChange={(e) => setRisk(e.target.value)}
                            className="h-9 text-xs shadow-xs"
                        />
                    </Field>

                    {strategy === "ema_cross" && (
                        <>
                            <Field label="Fast EMA">
                                <Input
                                    type="number"
                                    min="2"
                                    value={fast}
                                    onChange={(e) => setFast(e.target.value)}
                                    className="h-9 text-xs shadow-xs"
                                />
                            </Field>
                            <Field label="Slow EMA">
                                <Input
                                    type="number"
                                    min="3"
                                    value={slow}
                                    onChange={(e) => setSlow(e.target.value)}
                                    className="h-9 text-xs shadow-xs"
                                />
                            </Field>
                        </>
                    )}

                    {market === "futures" && (
                        <>
                            <Field label="Leverage (x)">
                                <Input
                                    type="number"
                                    min="1"
                                    max="125"
                                    step="1"
                                    value={leverage}
                                    onChange={(e) =>
                                        setLeverage(e.target.value)
                                    }
                                    className="h-9 text-xs shadow-xs"
                                />
                            </Field>
                            <Field label="Margin Mode">
                                <Select
                                    value={marginMode}
                                    onValueChange={(v) =>
                                        setMarginMode(v as "isolated" | "cross")
                                    }
                                >
                                    <SelectTrigger className="h-9 text-xs shadow-xs">
                                        <SelectValue />
                                    </SelectTrigger>
                                    <SelectContent>
                                        <SelectItem value="isolated">
                                            Isolated
                                        </SelectItem>
                                        <SelectItem value="cross">
                                            Cross
                                        </SelectItem>
                                    </SelectContent>
                                </Select>
                            </Field>
                            <Field label="Maintenance Margin %">
                                <Input
                                    type="number"
                                    min="0.1"
                                    max="25"
                                    step="0.1"
                                    value={maintenanceRate}
                                    onChange={(e) =>
                                        setMaintenanceRate(e.target.value)
                                    }
                                    className="h-9 text-xs shadow-xs"
                                />
                            </Field>
                        </>
                    )}

                    <Field label={t("backtest.ambiguity", "Same-candle SL/TP")}>
                        <Select value={ambiguity} onValueChange={setAmbiguity}>
                            <SelectTrigger className="h-9 text-xs shadow-xs">
                                <SelectValue />
                            </SelectTrigger>
                            <SelectContent>
                                <SelectItem value="conservative">
                                    Conservative — SL first
                                </SelectItem>
                                <SelectItem value="optimistic">
                                    Optimistic — TP first
                                </SelectItem>
                                <SelectItem value="skip">
                                    Skip ambiguous candle
                                </SelectItem>
                            </SelectContent>
                        </Select>
                    </Field>
                </div>

                <Button
                    type="button"
                    onClick={() => void run()}
                    disabled={loading}
                    className="h-9 text-xs font-semibold shadow-xs"
                >
                    {loading
                        ? t("backtest.running", "Running backtest…")
                        : t("backtest.run", "Run Backtest")}
                </Button>

                {error && (
                    <div className="rounded-xl border border-destructive/30 bg-destructive/10 p-3.5 text-xs text-destructive font-medium shadow-xs">
                        {error}
                    </div>
                )}

                {result && (
                    <div className="space-y-4 pt-2">
                        <div className="rounded-xl border border-emerald-500/20 bg-emerald-500/5 p-3.5 text-xs text-muted-foreground shadow-xs">
                            <span className="font-semibold text-foreground">
                                Chart overlay:
                            </span>{" "}
                            Entry/Exit markers are active. Click a trade row
                            below to show its exact SL/TP lines on the
                            candlestick chart.
                        </div>

                        <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-4">
                            <Metric
                                label="Net Profit"
                                value={money(result.summary.net_profit)}
                                tone={result.summary.net_profit >= 0}
                            />
                            <Metric
                                label="Return"
                                value={pct(result.summary.return_pct)}
                                tone={result.summary.return_pct >= 0}
                            />
                            <Metric
                                label="Win Rate"
                                value={`${result.summary.win_rate.toFixed(1)}%`}
                            />
                            <Metric
                                label="Profit Factor"
                                value={
                                    result.summary.profit_factor === null
                                        ? "∞"
                                        : result.summary.profit_factor.toFixed(
                                              2,
                                          )
                                }
                            />
                            <Metric
                                label="Expectancy"
                                value={money(result.summary.expectancy)}
                                tone={result.summary.expectancy >= 0}
                            />
                            <Metric
                                label="Max Drawdown"
                                value={`-${result.summary.max_drawdown_pct.toFixed(2)}%`}
                                tone={false}
                            />
                            <Metric
                                label="Fees"
                                value={money(result.summary.fees_paid)}
                            />
                            <Metric
                                label="Slippage"
                                value={money(result.summary.slippage_cost)}
                            />
                            <Metric
                                label="Funding P&L"
                                value={money(result.summary.funding_paid)}
                            />
                            {market === "futures" && (
                                <>
                                    <Metric
                                        label="Leverage"
                                        value={`${result.summary.leverage.toFixed(1)}x`}
                                    />
                                    <Metric
                                        label="Margin Mode"
                                        value={result.summary.margin_mode}
                                    />
                                    <Metric
                                        label="Liquidations"
                                        value={`${result.summary.liquidations}`}
                                    />
                                    <Metric
                                        label="Funding P&L"
                                        value={money(
                                            result.summary.funding_paid,
                                        )}
                                    />
                                </>
                            )}
                        </div>

                        <div className="rounded-xl border border-border bg-muted/20 p-4 shadow-xs">
                            <div className="mb-2 flex items-center justify-between text-xs font-semibold text-muted-foreground">
                                <span>Equity Curve</span>
                                <span>
                                    {money(result.summary.final_equity)}
                                </span>
                            </div>
                            <div className="flex h-24 items-end gap-px overflow-hidden">
                                {result.equity_curve.map((point, index) => {
                                    const min = Math.min(
                                        ...result.equity_curve.map(
                                            (x) => x.equity,
                                        ),
                                    );
                                    const range = Math.max(1, maxEquity - min);
                                    const height =
                                        8 + ((point.equity - min) / range) * 92;

                                    return (
                                        <div
                                            key={`${point.time}-${index}`}
                                            title={money(point.equity)}
                                            className="min-w-[2px] flex-1 rounded-t bg-emerald-400/70"
                                            style={{ height: `${height}%` }}
                                        />
                                    );
                                })}
                            </div>
                        </div>

                        <div className="overflow-x-auto rounded-xl border border-border shadow-xs">
                            <table className="w-full min-w-[760px] text-xs">
                                <thead className="bg-muted/50 text-left text-muted-foreground">
                                    <tr>
                                        <th className="px-3 py-2.5">#</th>
                                        <th className="px-3 py-2.5">Side</th>
                                        <th className="px-3 py-2.5">Entry</th>
                                        <th className="px-3 py-2.5">SL</th>
                                        <th className="px-3 py-2.5">TP</th>
                                        <th className="px-3 py-2.5">Exit</th>
                                        <th className="px-3 py-2.5">Reason</th>
                                        <th className="px-3 py-2.5 text-right">
                                            Net PnL
                                        </th>
                                    </tr>
                                </thead>
                                <tbody>
                                    {result.trades.map((trade, index) => (
                                        <tr
                                            key={`${trade.entry_time}-${index}`}
                                            onClick={() => selectTrade(index)}
                                            className={`cursor-pointer border-t border-border transition-colors ${
                                                selectedTrade === index
                                                    ? "bg-primary/10"
                                                    : "hover:bg-muted/40"
                                            }`}
                                            aria-selected={
                                                selectedTrade === index
                                            }
                                        >
                                            <td className="px-3 py-2.5">
                                                {index + 1}
                                            </td>
                                            <td
                                                className={`px-3 py-2.5 font-semibold ${trade.direction === "long" ? "text-emerald-500" : "text-red-500"}`}
                                            >
                                                {trade.direction.toUpperCase()}
                                            </td>
                                            <td className="px-3 py-2.5">
                                                {money(trade.entry_price)}
                                            </td>
                                            <td className="px-3 py-2.5 text-red-500">
                                                {money(trade.sl)}
                                            </td>
                                            <td className="px-3 py-2.5 text-emerald-500">
                                                {money(trade.tp)}
                                            </td>
                                            <td className="px-3 py-2.5">
                                                {money(trade.exit_price)}
                                            </td>
                                            <td className="px-3 py-2.5">
                                                {trade.reason.replaceAll(
                                                    "_",
                                                    " ",
                                                )}
                                            </td>
                                            <td
                                                className={`px-3 py-2.5 text-right font-semibold ${trade.net_pnl >= 0 ? "text-emerald-500" : "text-red-500"}`}
                                            >
                                                {trade.net_pnl >= 0 ? "+" : ""}
                                                {money(trade.net_pnl)}
                                            </td>
                                        </tr>
                                    ))}
                                </tbody>
                            </table>
                        </div>

                        <p className="text-[11px] leading-5 text-muted-foreground">
                            {result.note}
                        </p>
                    </div>
                )}
            </CardContent>
        </Card>
    );
}

function Field({ label, children }: { label: string; children: ReactNode }) {
    return (
        <label className="block text-xs font-medium text-muted-foreground space-y-1">
            <span className="block">{label}</span>
            {children}
        </label>
    );
}

function Metric({
    label,
    value,
    tone,
}: {
    label: string;
    value: string;
    tone?: boolean;
}) {
    return (
        <div className="rounded-xl border border-border bg-background p-3 shadow-xs">
            <div className="text-[10px] uppercase tracking-wider text-muted-foreground">
                {label}
            </div>
            <div
                className={`mt-1 text-base font-bold tabular-nums ${
                    tone === true
                        ? "text-emerald-500"
                        : tone === false
                          ? "text-red-500"
                          : "text-foreground"
                }`}
            >
                {value}
            </div>
        </div>
    );
}
