import { useEffect, useState } from "react";
import { Link } from "@inertiajs/react";
import {
    ArrowDownRight,
    ArrowUpRight,
    BarChart3,
    Coins,
    TrendingUp,
    Zap,
    Award,
    Flame,
    Star,
} from "lucide-react";

import { useI18n } from "@/lib/i18n";

type MarketMover = {
    symbol: string;
    last: number;
    change_pct: number;
    quote_volume: number;
};

type SortMode = "gainers" | "losers" | "volume";

type Props = {
    initialMarket: MarketMover[];
    /** @deprecated Kept for compatibility with existing dashboard props. */
    wsUrl?: string | null;
    limit?: number;
    sortMode?: SortMode;
    /** @deprecated Market movers now use HTTP polling instead of WebSocket. */
    wsDriver?: string | null;
    provider?: string;
};

// Fungsi untuk menentukan warna gradasi latar belakang kotak besar dan icon yang berbeda-beda
const getBoxTheme = (index: number) => {
    const themes = [
        {
            bg: "border-primary/20 bg-primary/10 text-primary",
            icon: <TrendingUp className="size-4" />,
        },
        {
            bg: "border-info/20 bg-info/10 text-info",
            icon: <Zap className="size-4" />,
        },
        {
            bg: "border-success/20 bg-success/10 text-success",
            icon: <Award className="size-4" />,
        },
    ];

    return themes[index % themes.length];
};

export default function MarketMoverLive({
    initialMarket,
    limit = 7,
    sortMode = "gainers",
    provider = "binance",
}: Props) {
    const { t } = useI18n();
    const [market, setMarket] = useState(initialMarket);
    useEffect(() => {
        setMarket(initialMarket.slice(0, limit));
    }, [initialMarket, limit]);

    useEffect(() => {
        let cancelled = false;
        let controller: AbortController | null = null;
        let intervalId: ReturnType<typeof setInterval> | null = null;

        const providerSlug = String(provider || "").trim().toLowerCase();
        if (!providerSlug) return;

        const refresh = async () => {
            if (cancelled || document.visibilityState === "hidden") return;

            controller?.abort();
            controller = new AbortController();

            try {
                const params = new URLSearchParams({ provider: providerSlug });
                const response = await fetch(`/dashboard/overview?${params.toString()}`, {
                    method: "GET",
                    headers: {
                        Accept: "application/json",
                        "X-Requested-With": "XMLHttpRequest",
                    },
                    cache: "no-store",
                    credentials: "same-origin",
                    signal: controller.signal,
                });

                if (!response.ok) return;

                const payload = await response.json();
                const nextMarket = payload?.market?.[sortMode];
                if (cancelled || !Array.isArray(nextMarket)) return;

                const normalized = nextMarket
                    .filter((item: unknown): item is MarketMover => {
                        if (!item || typeof item !== "object") return false;
                        const row = item as Record<string, unknown>;
                        return (
                            typeof row.symbol === "string" &&
                            Number.isFinite(Number(row.last)) &&
                            Number.isFinite(Number(row.change_pct)) &&
                            Number.isFinite(Number(row.quote_volume))
                        );
                    })
                    .slice(0, limit)
                    .map((item) => ({
                        symbol: item.symbol,
                        last: Number(item.last),
                        change_pct: Number(item.change_pct),
                        quote_volume: Number(item.quote_volume),
                    }));

                setMarket(normalized);
            } catch (error) {
                // Keep the last successful snapshot. Network failures are intentionally
                // silent so the browser console is not flooded with WebSocket/fetch noise.
                if (error instanceof DOMException && error.name === "AbortError") return;
            }
        };

        const handleVisibility = () => {
            if (document.visibilityState === "visible") void refresh();
        };

        // Keep the first render on the server-provided snapshot, then refresh
        // periodically over authenticated HTTP. No browser WebSocket is opened.
        intervalId = setInterval(() => void refresh(), 15_000);
        document.addEventListener("visibilitychange", handleVisibility);

        return () => {
            cancelled = true;
            controller?.abort();
            if (intervalId) clearInterval(intervalId);
            document.removeEventListener("visibilitychange", handleVisibility);
        };
    }, [provider, sortMode, limit]);

    const maxMetric = Math.max(
        1,
        ...market.map((item) =>
            sortMode === "volume"
                ? item.quote_volume
                : Math.abs(item.change_pct),
        ),
    );

    const formatPrice = (value: number): string => {
        if (!Number.isFinite(value)) return "—";
        if (value >= 1000)
            return value.toLocaleString(undefined, {
                maximumFractionDigits: 2,
            });
        if (value >= 1)
            return value.toLocaleString(undefined, {
                maximumFractionDigits: 4,
            });
        if (value >= 0.01)
            return value.toLocaleString(undefined, {
                maximumFractionDigits: 4,
            });
        return value.toLocaleString(undefined, { maximumFractionDigits: 8 });
    };

    const formatVolume = (value: number): string => {
        if (!Number.isFinite(value) || value < 0) return "—";
        if (value >= 1_000_000_000) {
            return `${(value / 1_000_000_000).toLocaleString(undefined, { maximumFractionDigits: 2 })}B`;
        }
        if (value >= 1_000_000) {
            return `${(value / 1_000_000).toLocaleString(undefined, { maximumFractionDigits: 2 })}M`;
        }
        if (value >= 1_000) {
            return `${(value / 1_000).toLocaleString(undefined, { maximumFractionDigits: 2 })}K`;
        }
        return value.toLocaleString(undefined, { maximumFractionDigits: 2 });
    };

    const baseName = (symbol: string) => symbol.replace(/USDT$/, "");
    const isLoading = false;

    return (
        <div className="mt-4">
            {market.length > 0 && (
                <div className="mb-3 flex items-center justify-between px-1">
                    <div className="flex items-center gap-2 text-[11px] font-medium text-muted-foreground dark:text-slate-400">
                        <span className="inline-flex size-1.5 rounded-full bg-success-500" />
                        Market snapshot
                    </div>
                    <span className="text-[11px] text-muted-foreground dark:text-slate-400">
                        Top {Math.min(limit, market.length)}
                    </span>
                </div>
            )}

            <div className="grid grid-cols-1 gap-2.5 sm:grid-cols-2">
                {isLoading &&
                    Array.from({ length: Math.min(limit, 6) }).map(
                        (_, index) => (
                            <div
                                key={`market-mover-skeleton-${index}`}
                                className="animate-pulse rounded-2xl border border-border/70 bg-card p-3.5 shadow-sm"
                                aria-hidden="true"
                            >
                                <div className="flex items-center gap-3">
                                    <div className="size-12 shrink-0 rounded-xl bg-slate-200 dark:bg-slate-800" />
                                    <div className="min-w-0 flex-1 space-y-2">
                                        <div className="flex items-center justify-between gap-2">
                                            <div className="h-3.5 w-20 rounded bg-slate-200 dark:bg-slate-800" />
                                            <div className="h-6 w-14 rounded-lg bg-slate-200 dark:bg-slate-800" />
                                        </div>
                                        <div className="h-2.5 w-14 rounded bg-slate-200 dark:bg-slate-800" />
                                        <div className="mt-2 flex items-end justify-between gap-3">
                                            <div className="space-y-1.5">
                                                <div className="h-3.5 w-24 rounded bg-slate-200 dark:bg-slate-800" />
                                                <div className="h-2.5 w-20 rounded bg-slate-200 dark:bg-slate-800" />
                                            </div>
                                            <div className="h-2.5 w-20 rounded bg-slate-200 dark:bg-slate-800" />
                                        </div>
                                    </div>
                                </div>
                                <div className="mt-3 h-1 overflow-hidden rounded-full bg-muted">
                                    <div className="h-full w-2/3 rounded-full bg-slate-200 dark:bg-slate-700" />
                                </div>
                            </div>
                        ),
                    )}

                {!isLoading &&
                    market.map((item, index) => {
                        const positive = item.change_pct >= 0;
                        const metric =
                            sortMode === "volume"
                                ? item.quote_volume
                                : Math.abs(item.change_pct);
                        const barWidth = Math.max(
                            8,
                            (metric / maxMetric) * 100,
                        );
                        const movementColor = positive
                            ? "text-success-600 dark:text-success-400"
                            : "text-destructive-600 dark:text-destructive-400";
                        const movementBg = positive
                            ? "bg-success-500/10 border-success-500/20"
                            : "bg-destructive-500/10 border-destructive-500/20";

                        const theme = getBoxTheme(index);

                        return (
                            <Link
                                key={item.symbol}
                                href={`/trading/${item.symbol}?provider=${encodeURIComponent(provider || "binance")}`}
                                className="group relative overflow-hidden rounded-2xl border border-border/70 bg-slate-50/60 dark:bg-slate-900/80 p-3.5 shadow-sm transition-all duration-200 hover:-translate-y-0.5 hover:border-slate-300 dark:hover:border-slate-700 hover:shadow-md"
                            >
                                <div className="flex items-center gap-3">
                                    {/* Kotak besar dengan warna gradasi dinamis & Icon di dalamnya */}
                                    <div className="relative shrink-0">
                                        <div
                                            className={`flex size-12 flex-col items-center justify-center rounded-xl shadow-sm ${theme.bg}`}
                                        >
                                            {theme.icon}
                                        </div>
                                        {/* Badge nomor urut kecil di pojok kanan atas dengan warna kontras */}
                                        <span className="absolute -right-1 -top-1 flex size-4 items-center justify-center rounded-full bg-warning-500 text-[9px] font-bold text-white ring-2 ring-white dark:ring-slate-900 shadow-2xs">
                                            {index + 1}
                                        </span>
                                    </div>

                                    <div className="min-w-0 flex-1">
                                        <div className="flex items-start justify-between gap-2">
                                            <div className="min-w-0">
                                                <div className="truncate text-[13px] font-bold text-slate-900 dark:text-slate-100">
                                                    {baseName(item.symbol)}
                                                </div>
                                                <div className="text-[10px] font-medium text-muted-foreground dark:text-slate-400">
                                                    USDT · 24h
                                                </div>
                                            </div>

                                            <div
                                                className={`inline-flex shrink-0 items-center gap-0.5 rounded-lg border px-1.5 py-1 text-[10px] font-bold tabular-nums ${movementBg} ${movementColor}`}
                                            >
                                                {positive ? (
                                                    <ArrowUpRight className="size-3" />
                                                ) : (
                                                    <ArrowDownRight className="size-3" />
                                                )}
                                                {positive ? "+" : ""}
                                                {item.change_pct.toFixed(2)}%
                                            </div>
                                        </div>

                                        <div className="mt-2 flex items-end justify-between gap-3">
                                            <div>
                                                <div className="text-[13px] font-semibold tabular-nums text-slate-800 dark:text-slate-200">
                                                    {formatPrice(item.last)}
                                                </div>
                                                <div className="mt-0.5 flex items-center gap-1 text-[10px] text-muted-foreground dark:text-slate-400">
                                                    <BarChart3 className="size-3" />
                                                    Vol{" "}
                                                    {formatVolume(
                                                        item.quote_volume,
                                                    )}
                                                </div>
                                            </div>
                                            {sortMode === "volume" && (
                                                <span className="text-[10px] font-semibold uppercase tracking-wide text-primary-600 dark:text-primary-400">
                                                    Volume leader
                                                </span>
                                            )}
                                        </div>
                                    </div>
                                </div>

                                <div className="mt-3 h-1 overflow-hidden rounded-full bg-slate-200 dark:bg-slate-800">
                                    <div
                                        className={`h-full rounded-full transition-[width] duration-500 ${positive ? "bg-success-500" : "bg-destructive-500"}`}
                                        style={{ width: `${barWidth}%` }}
                                        aria-hidden="true"
                                    />
                                </div>
                            </Link>
                        );
                    })}
            </div>

            {!market.length && (
                <div className="rounded-2xl border border-dashed border-border/70 bg-muted/30/60 p-8 text-center text-sm text-muted-foreground">
                    {t(
                        "dashboard.market_data_unavailable",
                        "Market data is not available yet.",
                    )}
                </div>
            )}

            <div className="mt-3 flex items-center justify-between px-1 text-[10px] text-muted-foreground dark:text-slate-400">
                <span>
                    {sortMode === "volume"
                        ? t("dashboard.volume_24h", "24h quote volume")
                        : t(
                              "dashboard.market_movement_24h",
                              "24h market movement",
                          )}
                </span>
                <span className="tabular-nums">
                    {t("dashboard.market_snapshot", "Snapshot")}
                </span>
            </div>
            <span className="sr-only" role="status" aria-live="polite">
                {t("dashboard.market_snapshot", "Market snapshot")}
            </span>
        </div>
    );
}
