import { useEffect, useRef, useState } from "react";
import { Activity, Gauge, TrendingDown, TrendingUp } from "lucide-react";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { DataCardState } from "./DataCardState";
import { useI18n } from "@/lib/i18n";
import { Badge } from "@/components/ui/badge";
import type { MarketType } from "@/lib/market";
import type { BtcMarketContext } from "@/types/insight";

interface Props {
    symbol: string;
    market: MarketType;
    interval: string;
    provider?: string;
}
interface RegimeData {
    regime: string;
    label: string;
    trend: { state: string; score: number };
    volatility: {
        state: string;
        atr_pct: number | null;
        bandwidth_pct: number | null;
    };
    metrics: {
        price: number;
        sma20: number | null;
        sma50: number | null;
        rsi14: number | null;
        atr14_pct: number | null;
        bb_bandwidth_pct: number | null;
        sample_size: number;
        as_of: number;
    };
    method: { signal_weighting: boolean };
    market_context?: BtcMarketContext | null;
}

export default function RegimeDetectionPanel({
    symbol,
    market,
    interval,
    provider = "binance",
}: Props) {
    const { t } = useI18n();
    const [data, setData] = useState<RegimeData | null>(null);
    const [error, setError] = useState<string | null>(null);
    const [loading, setLoading] = useState(false);
    const [retryKey, setRetryKey] = useState(0);
    const requestIdRef = useRef(0);

    useEffect(() => {
        if (market !== "futures") {
            setData(null);
            return;
        }
        const controller = new AbortController();
        const requestId = ++requestIdRef.current;
        setLoading(true);
        setError(null);
        setData(null);
        // Delay startup so React StrictMode's development-only effect replay
        // can clean up the first pass before it creates a network request.
        const startTimer = window.setTimeout(() => {
            void fetch(
                `/market/regime?${new URLSearchParams({
                    symbol,
                    market: "futures",
                    interval,
                    provider,
                }).toString()}`,
                {
                    headers: {
                        Accept: "application/json",
                        "X-Requested-With": "XMLHttpRequest",
                    },
                    credentials: "same-origin",
                    signal: controller.signal,
                    cache: "no-store",
                },
            )
                .then(async (response) => {
                    const payload: unknown = await response
                        .json()
                        .catch(() => null);
                    if (!response.ok) {
                        const message =
                            payload !== null &&
                            typeof payload === "object" &&
                            "message" in payload &&
                            typeof payload.message === "string"
                                ? payload.message
                                : `Regime API gagal (HTTP ${response.status}).`;
                        throw new Error(message);
                    }
                    return payload as RegimeData;
                })
                .then((next) => {
                    if (requestId !== requestIdRef.current) return;
                    setData(next);
                })
                .catch((err: unknown) => {
                    if (requestId !== requestIdRef.current) return;
                    if (
                        !(
                            err instanceof DOMException &&
                            err.name === "AbortError"
                        )
                    ) {
                        setError(
                            err instanceof Error
                                ? err.message
                                : "Regime data gagal dimuat.",
                        );
                    }
                })
                .finally(() => {
                    if (requestId === requestIdRef.current) {
                        setLoading(false);
                    }
                });
        }, 0);

        return () => {
            window.clearTimeout(startTimer);
            controller.abort();
        };
    }, [symbol, market, interval, provider, retryKey]);

    if (market !== "futures") return null;

    const trendIcon =
        data?.trend.state === "bullish"
            ? TrendingUp
            : data?.trend.state === "bearish"
              ? TrendingDown
              : Activity;
    const TrendIcon = trendIcon;

    return (
        <Card className="overflow-hidden border-border bg-card shadow-xs py-3 px-0!">
            <CardHeader className="border-b border-border/60 py-3">
                <div className="flex items-center justify-between gap-3">
                    <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">
                            <Gauge className="size-5" />
                        </div>
                        <div>
                            <div className="text-xs font-semibold text-foreground">
                                {t("Regime Detection", "Regime Detection")}
                            </div>
                            <div className="text-[11px] text-muted-foreground">
                                {symbol} · Futures · {interval}
                            </div>
                        </div>
                    </div>
                    {loading ? (
                        <div
                            className="h-7 w-24 animate-pulse rounded-full bg-muted"
                            role="status"
                            aria-label={t("Loading regime", "Loading regime")}
                        />
                    ) : (
                        data && (
                            <Badge
                                variant="secondary"
                                className="px-2.5 py-1 text-xs"
                            >
                                <TrendIcon className="mr-1.5 size-3.5" />
                                {(() => {
                                    const raw = data.label?.trim() ?? "";
                                    const normalized = raw.toLowerCase().replace(/[\s/-]+/g, "_");
                                    const mapped: Record<string, string> = {
                                        bullish_trend: "Bullish Trend",
                                        bearish_trend: "Bearish Trend",
                                        high_volatility: "High volatility",
                                        range: "Range / Mixed",
                                    };
                                    const label = mapped[normalized] ?? raw.replaceAll("_", " ");
                                    return t(label, label);
                                })()}
                            </Badge>
                        )
                    )}
                </div>
            </CardHeader>
            <CardContent className="p-4 pt-3 space-y-2.5">
                <DataCardState
                    loading={loading}
                    error={error}
                    hasData={Boolean(data)}
                    onRetry={() => setRetryKey((value) => value + 1)}
                    loadingLabel={t("Loading market regime…", "Loading market regime…")}
                    empty={!loading && !error && !data}
                    emptyLabel={t("Market regime is not available for this combination. Try refreshing to reload.", "Market regime belum tersedia untuk kombinasi ini. Coba refresh untuk memuat ulang.")}
                />
                {data && (
                    <>
                        <div className="grid gap-2 sm:grid-cols-3">
                            <Metric label={t("Trend", "Trend")} value={t(data.trend.state, data.trend.state)} />
                            <Metric
                                label={t("Volatility", "Volatility")}
                                value={t(data.volatility.state, data.volatility.state)}
                            />
                            <Metric
                                label="RSI 14"
                                value={format(data.metrics.rsi14)}
                            />
                        </div>
                        <div className="grid gap-2 sm:grid-cols-4">
                            <Metric
                                label="ATR 14"
                                value={format(data.metrics.atr14_pct, "%")}
                            />
                            <Metric
                                label="BB Bandwidth"
                                value={format(
                                    data.metrics.bb_bandwidth_pct,
                                    "%",
                                )}
                            />
                            <Metric
                                label="SMA Spread"
                                value={format(
                                    data.metrics.sma20 &&
                                        data.metrics.sma50 &&
                                        data.metrics.price
                                        ? ((data.metrics.sma20 -
                                              data.metrics.sma50) /
                                              data.metrics.price) *
                                              100
                                        : null,
                                    "%",
                                )}
                            />
                            <Metric
                                label="Sample size"
                                value={String(data.metrics.sample_size)}
                            />
                        </div>
                        {data.market_context && (
                            <BtcContextSummary context={data.market_context} />
                        )}
                        <div className="rounded-lg border border-border bg-muted/20 p-3 text-xs text-muted-foreground shadow-xs">
                            {t(
                                "BTC regime, dominance, and relative strength provide additional context. Altcoin price structure and timeframe confirmation still determine the setup; BTC context does not automatically block a signal.",
                                "BTC regime, dominasi, dan kekuatan relatif adalah konteks tambahan. Struktur harga altcoin dan konfirmasi timeframe tetap menentukan setup; konteks BTC tidak memblokir sinyal secara otomatis.",
                            )}
                        </div>
                    </>
                )}
            </CardContent>
        </Card>
    );
}

function format(value: number | null | undefined, suffix = "") {
    return value == null || !Number.isFinite(value)
        ? "—"
        : `${value.toFixed(2)}${suffix}`;
}

function Metric({ label, value }: { label: string; value: string }) {
    return (
        <div className="rounded-lg border border-border bg-background/70 p-2.5 shadow-xs">
            <div className="text-[10px] font-semibold uppercase tracking-wider text-muted-foreground">
                {label}
            </div>
            <div className="mt-0.5 text-sm font-bold capitalize text-foreground">
                {value}
            </div>
        </div>
    );
}
function BtcContextSummary({ context }: { context: BtcMarketContext }) {
    const relative = context.relative_strength;
    return (
        <div className="rounded-xl border border-primary/20 bg-primary/[0.03] p-3 space-y-2.5">
            <div className="flex flex-wrap items-center justify-between gap-2">
                <div className="text-xs font-semibold text-foreground">
                    BTC market context
                </div>
                <Badge variant="outline" className="text-[10px]">
                    {context.provider.toUpperCase()} · {context.interval}
                </Badge>
            </div>
            <div className="grid grid-cols-1 gap-2 sm:grid-cols-3">
                <Metric
                    label="BTC trend"
                    value={context.btc.available ? context.btc.state : "—"}
                />
                <Metric
                    label="BTC dominance"
                    value={format(context.btc_dominance_pct, "%")}
                />
                <Metric
                    label="ALT/BTC · 20 candles"
                    value={
                        relative.available
                            ? `${format(relative.alt_btc_return_pct, "%")} · ${relative.label}`
                            : relative.label
                    }
                />
            </div>
            <p className="text-[11px] leading-5 text-muted-foreground">
                Dominasi BTC adalah snapshot global. ALT/BTC dihitung dari
                candle quote yang selaras; bila datanya tidak cukup, metrik
                ditandai tidak tersedia.
            </p>
        </div>
    );
}
