"use client";

import { Wallet } from "lucide-react";
import Image from "next/image";
import { useRouter, useSearchParams } from "next/navigation";
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";

import { getWalletBalance, getWalletLogs } from "@/api/wallet";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { PlayerPanel } from "@/components/layout/player-panel";
import {
  TransferInDialog,
  TransferOutDialog,
} from "@/features/wallet/wallet-transfer-dialogs";
import { PlayerMoneyDisplay } from "@/components/player-money-display";
import { WalletLogsBlock } from "@/features/wallet/wallet-logs-block";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
import { isCreditFundingPlayer } from "@/lib/player-funding-mode";
import { formatMinorAsCurrency } from "@/lib/money";
import { PLAYER_CURRENCY_CHANGE_EVENT } from "@/lib/player-currency-preference";
import { formatWalletClientError } from "@/lib/wallet-api-error";
import { usePlayerSessionStore } from "@/stores/player-session-store";
import type { WalletBalanceData } from "@/types/api/wallet-balance";
import { getWalletLogsLastPage, type WalletLogsData } from "@/types/api/wallet-logs";

const WALLET_LOGS_PAGE_SIZE = 10;

function scrollToWalletSection(id: string): void {
  if (typeof document === "undefined") return;
  document.getElementById(id)?.scrollIntoView({ behavior: "smooth", block: "start" });
}

export function WalletScreen() {
  const router = useRouter();
  const searchParams = useSearchParams();
  const { activeCurrency: currency } = useActivePlayerCurrency();
  const { t } = useTranslation("player");
  const [transferInOpen, setTransferInOpen] = useState(false);
  const [transferOutOpen, setTransferOutOpen] = useState(false);
  const [balance, setBalance] = useState<WalletBalanceData | null>(null);
  const [logs, setLogs] = useState<WalletLogsData | null>(null);
  const [filter, setFilter] = useState("");
  const [loading, setLoading] = useState(true);
  const [logsLoading, setLogsLoading] = useState(false);
  const [loadingMore, setLoadingMore] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const loadMoreRef = useRef<HTMLDivElement | null>(null);

  const filterInitializedRef = useRef(false);
  const prevFilterRef = useRef("");
  const actionDeepLinkHandledRef = useRef(false);
  const sectionDeepLinkHandledRef = useRef(false);

  const profile = usePlayerSessionStore((s) => s.profile);
  const isCreditPlayer = isCreditFundingPlayer(balance) || isCreditFundingPlayer(profile);

  useEffect(() => {
    if (actionDeepLinkHandledRef.current || loading) return;
    const action = searchParams.get("action");
    if (action !== "transfer-in" && action !== "transfer-out") return;

    actionDeepLinkHandledRef.current = true;
    if (!isCreditPlayer) {
      if (action === "transfer-in") {
        setTransferInOpen(true);
      } else {
        setTransferOutOpen(true);
      }
    }
    router.replace("/wallet", { scroll: false });
  }, [isCreditPlayer, loading, router, searchParams]);

  useEffect(() => {
    if (sectionDeepLinkHandledRef.current || loading) return;
    const section = searchParams.get("section");
    if (section !== "logs" && section !== "pending") return;

    sectionDeepLinkHandledRef.current = true;
    const targetId = "wallet-logs";
    const timer = window.setTimeout(() => {
      scrollToWalletSection(targetId);
      router.replace("/wallet", { scroll: false });
    }, 120);
    return () => window.clearTimeout(timer);
  }, [isCreditPlayer, loading, router, searchParams]);

  const loadLogs = useCallback(async (targetPage = 1, append = false) => {
    const nextLogs = await getWalletLogs({
      page: targetPage,
      size: WALLET_LOGS_PAGE_SIZE,
      type: filter || undefined,
      currency,
    });
    setLogs((current) =>
      append && current
        ? { ...nextLogs, items: [...current.items, ...nextLogs.items] }
        : nextLogs,
    );
    return nextLogs;
  }, [currency, filter]);

  useEffect(() => {
    let cancelled = false;

    void (async () => {
      setError(null);
      setLoading(true);
      try {
        const [b, nextLogs] = await Promise.all([
          getWalletBalance({ currency }),
          getWalletLogs({
            page: 1,
            size: WALLET_LOGS_PAGE_SIZE,
            type: filter || undefined,
            currency,
          }),
        ]);
        if (cancelled) return;
        setBalance(b);
        setLogs(nextLogs);
      } catch (e) {
        if (!cancelled) {
          setError(formatWalletClientError(e, t));
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
          setLogsLoading(false);
        }
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [currency, t]); // eslint-disable-line react-hooks/exhaustive-deps -- 币种切换整页刷新；流水筛选见下方 effect

  useEffect(() => {
    if (!filterInitializedRef.current) {
      filterInitializedRef.current = true;
      prevFilterRef.current = filter;
      return;
    }
    if (prevFilterRef.current === filter) {
      return;
    }
    prevFilterRef.current = filter;

    let cancelled = false;
    setError(null);
    setLogsLoading(true);

    void (async () => {
      try {
        const nextLogs = await getWalletLogs({
          page: 1,
          size: WALLET_LOGS_PAGE_SIZE,
          type: filter || undefined,
          currency,
        });
        if (!cancelled) {
          setLogs(nextLogs);
        }
      } catch (e) {
        if (!cancelled) {
          setError(formatWalletClientError(e, t));
        }
      } finally {
        if (!cancelled) {
          setLogsLoading(false);
        }
      }
    })();

    return () => {
      cancelled = true;
    };
  }, [currency, filter, t]);

  const refreshAll = useCallback(async () => {
    setError(null);
    setLogsLoading(true);
    try {
      // 并行请求余额和日志
      const [b] = await Promise.all([
        getWalletBalance({ currency }),
        loadLogs(1, false),
      ]);
      setBalance(b);
    } catch (e) {
      setError(formatWalletClientError(e, t));
    } finally {
      setLogsLoading(false);
      setLoading(false);
    }
  }, [currency, loadLogs, t]);

  useEffect(() => {
    const onCurrencyChange = () => void refreshAll();
    window.addEventListener(PLAYER_CURRENCY_CHANGE_EVENT, onCurrencyChange);
    return () => window.removeEventListener(PLAYER_CURRENCY_CHANGE_EVENT, onCurrencyChange);
  }, [refreshAll]);

  const hasMore = logs ? logs.page < getWalletLogsLastPage(logs) : false;

  const displayMinor = isCreditPlayer
    ? Number(balance?.available_balance ?? 0)
    : Number(balance?.balance ?? 0);

  const loadMore = useCallback(() => {
    if (!logs || !hasMore || loadingMore) return;

    setError(null);
    setLoadingMore(true);
    void loadLogs(logs.page + 1, true)
      .catch((e) => {
        setError(formatWalletClientError(e, t));
      })
      .finally(() => {
        setLoadingMore(false);
      });
  }, [hasMore, loadLogs, loadingMore, logs, t]);

  useEffect(() => {
    const target = loadMoreRef.current;
    if (!target || loading || logsLoading || loadingMore || !hasMore) return;

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry?.isIntersecting) {
          loadMore();
        }
      },
      { rootMargin: "160px" },
    );

    observer.observe(target);
    return () => observer.disconnect();
  }, [hasMore, loadMore, loading, loadingMore, logsLoading]);

  return (
    <PlayerPanel
      title={isCreditPlayer ? t("wallet.creditTitle", { defaultValue: "信用" }) : t("wallet.title")}
    >
      <div className="space-y-3">
        {error ? (
          <div className="rounded-xl border border-red-200 bg-red-50 px-3 py-3 text-sm text-red-700">
            <p>{error}</p>
            <Button
              type="button"
              className="mt-3 bg-[#e5002c] text-white hover:bg-[#d10028]"
              onClick={() => void refreshAll()}
            >
              {t("actions.retry")}
            </Button>
          </div>
        ) : null}

        <section className="relative overflow-hidden rounded-xl bg-[#e5002c] px-3 py-4 text-white shadow-[0_10px_28px_rgba(229,0,44,0.25)]">
          <Image
            src="/entry/image5.png"
            alt=""
            fill
            className="pointer-events-none object-cover object-center"
            aria-hidden
          />
          <div className="relative flex items-center gap-3">
            <div className="flex size-14 shrink-0 items-center justify-center rounded-full bg-white text-[#d81435] shadow-sm">
              <Wallet className="size-7" aria-hidden />
            </div>
            <div className="min-w-0 flex-1">
              <p className="text-sm font-semibold text-white/90">
                {isCreditPlayer
                  ? t("wallet.creditAvailable", { defaultValue: "可用信用" })
                  : t("wallet.balance")}
              </p>
              {loading ? (
                <Skeleton className="mt-2 h-8 w-44 rounded-md bg-white/25" />
              ) : (
                <PlayerMoneyDisplay
                  amountMinor={displayMinor}
                  currency={currency}
                  className="mt-1 text-white"
                />
              )}
              <p className="mt-2 text-xs text-white/75">
                {isCreditPlayer
                  ? t("wallet.creditSummary", {
                      defaultValue: "授信 {{limit}} · 已用 {{used}}",
                      limit: formatMinorAsCurrency(balance?.credit_limit ?? 0, currency),
                      used: formatMinorAsCurrency(balance?.used_credit ?? 0, currency),
                    })
                  : t("wallet.available", {
                      amount: formatMinorAsCurrency(balance?.available_balance ?? 0, currency),
                    })}
              </p>
            </div>
          </div>
        </section>

        {!isCreditPlayer ? (
          <div className="grid grid-cols-2 gap-3">
            <TransferInDialog
              idPrefix="wallet-"
              currency={currency}
              lotteryMinor={Number(balance?.balance ?? 0)}
              mainMinor={
                balance?.main_balance === null || balance?.main_balance === undefined
                  ? null
                  : Number(balance.main_balance)
              }
              onSuccess={refreshAll}
              triggerVariant="hall"
              triggerLabel={t("wallet.transferIn", { defaultValue: "Transfer In" })}
              triggerClassName="h-14 rounded-2xl text-base font-black"
              open={transferInOpen}
              onOpenChange={setTransferInOpen}
            />
            <TransferOutDialog
              idPrefix="wallet-"
              currency={currency}
              availableMinor={Number(balance?.available_balance ?? 0)}
              onSuccess={refreshAll}
              triggerVariant="hall"
              triggerLabel={t("wallet.transferOut", { defaultValue: "Transfer Out" })}
              triggerClassName="h-14 rounded-2xl text-base font-black"
              open={transferOutOpen}
              onOpenChange={setTransferOutOpen}
            />
          </div>
        ) : null}

        <div id="wallet-logs" className="scroll-mt-3">
        <WalletLogsBlock
          creditMode={isCreditPlayer}
          logs={logs}
          logsLoading={loading || logsLoading}
          loadingMore={loadingMore}
          hasMore={hasMore}
          onLoadMore={loadMore}
          loadMoreRef={loadMoreRef}
          filter={filter}
          onFilterChange={setFilter}
          currency={currency}
        />
        </div>
      </div>
    </PlayerPanel>
  );
}
