import { Search, Star, Sparkles, TrendingUp } from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import {
    Sheet,
    SheetContent,
    SheetDescription,
    SheetHeader,
    SheetTitle,
    SheetTrigger,
} from "@/components/ui/sheet";
import { Input } from "@/components/ui/input";
import { Toggle } from "@/components/ui/toggle";
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
import { usePolledJson } from "@/hooks/use-polled-json";
import { formatPrice, type MarketType } from "@/lib/market";
import { useI18n } from "@/lib/i18n";

export interface CoinListItem {
    symbol: string;
    name: string;
}

export interface CoinListTicker {
    symbol: string;
    last: number;
    change_pct: number;
    quote_volume: number;
}

interface CoinListSheetProps {
    symbol: string;
    market: MarketType;
    /** Provider yang sama dengan context Trading/HeaderCoinSearch. */
    provider?: string;
    symbols: Record<MarketType, CoinListItem[]>;
    tickers: Record<string, CoinListTicker>;
    watchlist: string[];
    onToggleFavorite: (symbol: string, market: MarketType) => void;
    onSelect: (symbol: string, market: MarketType) => void;
}

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

const normalizeSymbol = (value: string) =>
    value
        .trim()
        .toUpperCase()
        .replace(/[\s/_-]/g, "");

const normalizeWatchlistKey = (value: string) => {
    const [rawMarket, ...rawSymbol] = value.split(":");
    if (!rawMarket || rawSymbol.length === 0) return value;

    const normalizedMarket = rawMarket.trim().toLowerCase();
    if (normalizedMarket !== "spot" && normalizedMarket !== "futures") {
        return value;
    }

    return `${normalizedMarket}:${normalizeSymbol(rawSymbol.join(":"))}`;
};

const TABS: { value: MarketType; label: string; hint: string }[] = [
    { value: "spot", label: "Spot", hint: "Spot" },
    { value: "futures", label: "Futures", hint: "Perpetual USDT-M" },
];

const tabItemClass =
    "h-9 flex-1 rounded-md text-xs font-semibold tracking-wide text-muted-foreground transition-all duration-200 hover:text-foreground data-[state=on]:bg-gradient-to-r data-[state=on]:from-warning-500 data-[state=on]:to-orange-500 data-[state=on]:text-white data-[state=on]:shadow-md data-[state=on]:shadow-warning-500/20";

export default function CoinListSheet({
    symbol,
    market,
    provider = "binance",
    symbols,
    tickers,
    watchlist,
    onToggleFavorite,
    onSelect,
}: CoinListSheetProps) {
    const { t: translate } = useI18n();
    const [open, setOpen] = useState(false);
    const [tab, setTab] = useState<MarketType>(market);
    const [search, setSearch] = useState("");
    const [showFavoritesOnly, setShowFavoritesOnly] = useState(false);
    const activeRef = useRef<HTMLDivElement | null>(null);

    const normalizedWatchlist = useMemo(
        () =>
            new Set(
                watchlist
                    .filter((key): key is string => typeof key === "string")
                    .map(normalizeWatchlistKey),
            ),
        [watchlist],
    );

    const other = usePolledJson<CoinListTicker[]>(
        `/market/tickers?market=${tab}&provider=${encodeURIComponent(provider)}`,
        5000,
        open && tab !== market,
    );

    const tabTickers = useMemo<Record<string, CoinListTicker>>(
        () =>
            tab === market
                ? tickers
                : Object.fromEntries(
                      (other.data ?? []).map((t) => [t.symbol, t]),
                  ),
        [tab, market, tickers, other.data],
    );

    const list = symbols[tab] ?? [];
    const tabFavoritePrefix = `${tab}:`;

    const isFavorite = (coinSymbol: string) =>
        normalizedWatchlist.has(
            `${tabFavoritePrefix}${normalizeSymbol(coinSymbol)}`,
        );

    const favoriteCount = useMemo(
        () =>
            [...normalizedWatchlist].filter((key) =>
                key.startsWith(tabFavoritePrefix),
            ).length,
        [normalizedWatchlist, tabFavoritePrefix],
    );

    const visibleSymbols = useMemo(() => {
        let result = list;

        if (showFavoritesOnly) {
            result = result.filter((s) => isFavorite(s.symbol));
        }

        const q = search.trim().toLowerCase();
        if (!q) return result;

        return result.filter(
            (s) =>
                s.symbol.toLowerCase().includes(q) ||
                s.name.toLowerCase().includes(q),
        );
    }, [
        search,
        list,
        showFavoritesOnly,
        normalizedWatchlist,
        tabFavoritePrefix,
    ]);

    useEffect(() => {
        if (!open || search || showFavoritesOnly) return;

        const id = requestAnimationFrame(() =>
            activeRef.current?.scrollIntoView({ block: "center" }),
        );

        return () => cancelAnimationFrame(id);
    }, [open, tab, search, showFavoritesOnly]);

    const handleOpenChange = (next: boolean) => {
        setOpen(next);
        if (next) {
            setTab(market);
        } else {
            setSearch("");
            setShowFavoritesOnly(false);
        }
    };

    const handleSelect = (next: string) => {
        onSelect(next, tab);
        handleOpenChange(false);
    };

    const tabInfo = TABS.find((t) => t.value === tab)!;

    return (
        <Sheet open={open} onOpenChange={handleOpenChange}>
            <SheetTrigger asChild>
                <Button
                    variant="outline"
                    size="sm"
                    className="group relative gap-2 overflow-hidden rounded-xl border-border/80 bg-gradient-to-b from-background to-muted/40 px-3.5 text-xs font-medium text-foreground shadow-sm transition-all duration-200 hover:border-warning-500/50 hover:bg-accent hover:shadow-warning-500/10"
                >
                    <div className="absolute inset-0 bg-gradient-to-r from-warning-500/0 via-warning-500/5 to-warning-500/0 opacity-0 transition-opacity duration-300 group-hover:opacity-100" />
                    <Search className="size-3.5 text-warning-500 transition-transform duration-200 group-hover:scale-110" />
                    <span>{translate("Search Coin")}</span>
                </Button>
            </SheetTrigger>

            <SheetContent
                side="left"
                className="w-full gap-0 border-border/60 bg-background/95 backdrop-blur-xl p-0 text-foreground sm:max-w-md flex flex-col shadow-2xl"
            >
                {/* Header Section */}
                <SheetHeader className="border-b border-border/60 p-5 space-y-4">
                    <div className="flex items-center justify-between">
                        <div>
                            <SheetTitle className="flex items-center gap-2 text-lg font-bold tracking-tight text-foreground">
                                <TrendingUp className="size-5 text-warning-500" />
                                {translate("Market")}
                            </SheetTitle>
                            <SheetDescription className="text-xs text-muted-foreground mt-0.5 ms-7">
                                {translate("Market :market · Provider :provider", {
                                    market: tabInfo.hint,
                                    provider: provider.toUpperCase(),
                                })}
                            </SheetDescription>
                        </div>
                    </div>

                    {/* Market Toggle Group */}
                    <ToggleGroup
                        type="single"
                        value={tab}
                        onValueChange={(v) => {
                            if (v) setTab(v as MarketType);
                        }}
                        className="w-full gap-1.5 rounded-xl bg-muted/40 p-1.5 border border-border/60 shadow-inner"
                        aria-label={translate("Market type")}
                    >
                        {TABS.map((t) => (
                            <ToggleGroupItem
                                key={t.value}
                                value={t.value}
                                className={tabItemClass}
                            >
                                {t.label}
                            </ToggleGroupItem>
                        ))}
                    </ToggleGroup>

                    {/* Search & Filter Bar */}
                    <div className="space-y-2.5 pt-1">
                        <div className="relative">
                            <Search className="absolute left-3.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
                            <label htmlFor="market-search" className="sr-only">
                                {translate("Search Coin")}
                            </label>
                            <Input
                                id="market-search"
                                value={search}
                                onChange={(e) => setSearch(e.target.value)}
                                placeholder="ex. BTC, ETH, BNB..."
                                autoComplete="off"
                                className="h-10 w-full rounded-xl border-border/80 bg-muted/30 pl-10 pr-4 text-sm transition-all placeholder:text-muted-foreground/70 focus-visible:border-warning-500 focus-visible:ring-2 focus-visible:ring-warning-500/20"
                            />
                        </div>

                        <div className="flex items-center justify-between">
                            <Toggle
                                type="button"
                                pressed={showFavoritesOnly}
                                onPressedChange={setShowFavoritesOnly}
                                variant="outline"
                                size="sm"
                                className="h-8 gap-2 rounded-lg border-border/80 bg-muted/30 px-3 text-xs font-medium text-muted-foreground transition-all hover:bg-accent hover:text-accent-foreground data-[state=on]:border-warning-500/40 data-[state=on]:bg-warning-500/15 data-[state=on]:text-warning-600 dark:data-[state=on]:text-warning-400"
                            >
                                <Star
                                    className={`size-3.5 transition-colors ${
                                        showFavoritesOnly
                                            ? "fill-warning-400 text-warning-400"
                                            : "text-muted-foreground"
                                    }`}
                                />
                                {translate("Favorite watchlist")}
                                <span className="ml-0.5 rounded-full bg-background/80 px-1.5 py-0.2 text-[10px] font-bold shadow-xs">
                                    {favoriteCount}
                                </span>
                            </Toggle>

                            <span className="text-[11px] text-muted-foreground/80 font-medium">
                                {translate("Showing :count coins", {
                                    count: visibleSymbols.length,
                                })}
                            </span>
                        </div>
                    </div>
                </SheetHeader>

                {/* Coin List Items */}
                <ul className="flex-1 divide-y divide-border/40 overflow-y-auto px-3 py-2 scrollbar-thin scrollbar-thumb-muted">
                    {visibleSymbols.map((item) => {
                        const ticker = tabTickers[item.symbol];
                        const active = tab === market && item.symbol === symbol;
                        const isFav = isFavorite(item.symbol);
                        const isPositive = ticker ? ticker.change_pct >= 0 : true;

                        return (
                            <li key={item.symbol} className="py-1">
                                <div
                                    ref={active ? activeRef : undefined}
                                    className={`group relative flex w-full items-center justify-between gap-2 px-3 py-3 transition-all duration-200 rounded-xl border ${
                                        active
                                            ? "border-warning-500/40 bg-gradient-to-r from-warning-500/10 via-warning-500/5 to-transparent shadow-xs"
                                            : "border-transparent hover:border-border/60 hover:bg-muted/40"
                                    }`}
                                >
                                    <Toggle
                                        type="button"
                                        pressed={isFav}
                                        onPressedChange={() =>
                                            onToggleFavorite(item.symbol, tab)
                                        }
                                        onClick={(e) => e.stopPropagation()}
                                        variant="outline"
                                        size="sm"
                                        aria-label={
                                            isFav
                                                ? translate(
                                                      "Remove :symbol from favorites",
                                                      { symbol: pair(item.symbol) },
                                                  )
                                                : translate(
                                                      "Add :symbol to favorites",
                                                      { symbol: pair(item.symbol) },
                                                  )
                                        }
                                        title={
                                            isFav
                                                ? translate("Remove from favorites")
                                                : translate("Add to favorites")
                                        }
                                        className="size-8 min-w-8 rounded-lg border-0 bg-transparent p-0 text-muted-foreground hover:bg-muted hover:text-warning-500 data-[state=on]:bg-transparent data-[state=on]:text-warning-500"
                                    >
                                        <Star
                                            className={`size-4 transition-transform duration-200 group-hover:scale-110 ${
                                                isFav
                                                    ? "fill-warning-400 text-warning-400"
                                                    : "text-muted-foreground/60 hover:text-warning-400"
                                            }`}
                                        />
                                    </Toggle>

                                    <Button
                                        type="button"
                                        variant="ghost"
                                        onClick={() =>
                                            handleSelect(item.symbol)
                                        }
                                        aria-current={active}
                                        className="h-auto flex-1 justify-between rounded-none px-2 py-0 text-left font-normal hover:bg-transparent"
                                    >
                                        <span className="min-w-0 pr-2">
                                            <span className="flex items-center gap-2">
                                                <span className="text-sm font-bold tracking-tight text-foreground">
                                                    {pair(item.symbol)}
                                                </span>
                                                {tab === "futures" && (
                                                    <span className="inline-flex items-center rounded-md bg-warning-500/10 px-1.5 py-0.5 text-[9px] font-bold tracking-wider text-warning-600 dark:text-warning-400 border border-warning-500/20">
                                                        PERP
                                                    </span>
                                                )}
                                                {active && (
                                                    <span className="flex h-1.5 w-1.5 rounded-full bg-warning-500 animate-pulse" />
                                                )}
                                            </span>
                                            <span className="block truncate text-xs font-medium text-muted-foreground/80 mt-0.5">
                                                {item.name}
                                            </span>
                                        </span>

                                        <span className="text-right tabular-nums">
                                            <span className="block text-sm font-semibold text-foreground tracking-tight">
                                                {ticker ? formatPrice(ticker.last) : "–"}
                                            </span>
                                            {ticker ? (
                                                <span
                                                    className={`inline-block mt-1 rounded-md px-2 py-0.5 text-xs font-bold tracking-wide ${
                                                        isPositive
                                                            ? "bg-success-500/10 text-success-600 dark:text-success-400 border border-success-500/20"
                                                            : "bg-destructive-500/10 text-destructive-600 dark:text-destructive-400 border border-destructive-500/20"
                                                    }`}
                                                >
                                                    {isPositive ? "+" : ""}
                                                    {ticker.change_pct.toFixed(2)}%
                                                </span>
                                            ) : (
                                                <span className="block text-xs text-muted-foreground">
                                                    –
                                                </span>
                                            )}
                                        </span>
                                    </Button>
                                </div>
                            </li>
                        );
                    })}

                    {list.length === 0 && (
                        <div className="flex flex-col items-center justify-center px-4 py-12 text-center">
                            <div className="rounded-full bg-muted/60 p-3 mb-3 border border-border/60">
                                <Sparkles className="size-6 text-muted-foreground" />
                            </div>
                            <p className="text-sm font-semibold text-foreground">
                                {translate("No :type list is available.", {
                                    type: tabInfo.hint,
                                })}
                            </p>
                            <p className="text-xs text-muted-foreground mt-1">
                                {translate("Please try again in a moment.")}
                            </p>
                        </div>
                    )}

                    {list.length > 0 && visibleSymbols.length === 0 && (
                        <div className="flex flex-col items-center justify-center px-4 py-12 text-center">
                            <div className="rounded-full bg-warning-500/10 p-3 mb-3 border border-warning-500/20">
                                <Search className="size-6 text-warning-500" />
                            </div>
                            <p className="text-sm font-semibold text-foreground">
                                {translate("No assets found")}
                            </p>
                            <p className="text-xs text-muted-foreground mt-1 max-w-[240px]">
                                {showFavoritesOnly
                                    ? translate("No coins have been added to favorites yet.")
                                    : translate("No coins match your search.")}
                            </p>
                        </div>
                    )}
                </ul>
            </SheetContent>
        </Sheet>
    );
}
