"use client";

import Link from "next/link";
import { CalendarIcon, XIcon } from "lucide-react";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next";

import { getDrawResults } from "@/api/draw";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
import { Skeleton } from "@/components/ui/skeleton";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { PlayerPanel } from "@/components/layout/player-panel";
import { JackpotResultsStrip } from "@/features/results/jackpot-results-strip";
import { TwentyThreeResultsGrid } from "@/features/results/twenty-three-results-grid";
import { useCurrencyCatalog } from "@/hooks/use-currency-catalog";
import { formatPlayerInstant } from "@/lib/player-datetime";
import { useActivePlayerCurrency } from "@/hooks/use-active-player-currency";
import { resultsPrizeLabelKey, RESULTS_TOP_PRIZE_KEYS } from "@/lib/results-prize-labels";
import type { DrawResultListItem } from "@/types/api/draw-results";

const RESULTS_PAGE_SIZE = 10;

const MONTH_OPTIONS = Array.from({ length: 12 }, (_, value) => ({
  value,
  labelKey: `calendar.months.${value + 1}`,
}));

export function DrawResultsListScreen() {
  const { t } = useTranslation("player");
  useCurrencyCatalog();
  const [items, setItems] = useState<DrawResultListItem[] | null>(null);
  const [error, setError] = useState<string | null>(null);
  const [date, setDate] = useState("");
  const [datePickerOpen, setDatePickerOpen] = useState(false);
  const [calendarMonth, setCalendarMonth] = useState(() => new Date());
  const [page, setPage] = useState(1);
  const [lastPage, setLastPage] = useState(1);
  const [loading, setLoading] = useState(true);
  const [loadingMore, setLoadingMore] = useState(false);
  const loadMoreRef = useRef<HTMLDivElement | null>(null);
  const selectedDate = useMemo(() => parseBusinessDate(date), [date]);
  const businessDate = /^\d{4}-\d{2}-\d{2}$/.test(date) ? date : undefined;
  const quickYears = useMemo(() => buildYearOptions(calendarMonth), [calendarMonth]);
  const featured = items?.[0] ?? null;
  const { activeCurrency } = useActivePlayerCurrency();
  const jackpotCurrency = featured?.jackpot?.currency_code ?? activeCurrency;

  const fetchList = useCallback(async (targetPage = 1, append = false) => {
    setError(null);
    if (append) {
      setLoadingMore(true);
    } else {
      setLoading(true);
    }

    try {
      const res = await getDrawResults({
        page: targetPage,
        size: RESULTS_PAGE_SIZE,
        business_date: businessDate,
        currency: activeCurrency,
      });
      setItems((current) => (append && current ? [...current, ...res.items] : res.items));
      setPage(res.page);
      setLastPage(res.last_page);
    } catch {
      setError(t("results.loadFailed"));
      if (!append) {
        setItems(null);
      }
    } finally {
      if (append) {
        setLoadingMore(false);
      } else {
        setLoading(false);
      }
    }
  }, [activeCurrency, businessDate, t]);

  useEffect(() => {
    queueMicrotask(() => {
      void fetchList(1, false);
    });
  }, [fetchList]);

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

    const observer = new IntersectionObserver(
      ([entry]) => {
        if (entry?.isIntersecting) {
          void fetchList(page + 1, true);
        }
      },
      { rootMargin: "160px" },
    );

    observer.observe(target);
    return () => observer.disconnect();
  }, [fetchList, lastPage, loading, loadingMore, page]);

  return (
    <PlayerPanel title={t("results.title")}>
      <div className="space-y-3">
        <JackpotResultsStrip currencyCode={jackpotCurrency} />

        <div className="rounded-xl border border-[#e6edf8] bg-[#f8fbff] p-3">
          <p className="mb-2 text-xs font-bold text-[#32518d]">
            {t("results.businessDate")}
          </p>
          <div className="flex gap-2">
            <Popover open={datePickerOpen} onOpenChange={setDatePickerOpen}>
              <PopoverTrigger
                render={
                  <Button
                    type="button"
                    variant="outline"
                    className="h-10 flex-1 justify-start rounded-lg border-[#dce7f7] bg-white px-3 text-left text-sm font-semibold text-[#32518d] hover:bg-[#f8fbff]"
                  >
                    <CalendarIcon className="mr-2 size-4 text-[#7890b8]" />
                    {date ||
                      t("results.selectBusinessDate", {
                        defaultValue: "选择日期",
                      })}
                  </Button>
                }
              />
              <PopoverContent align="start" className="w-auto border-[#dce7f7] p-2 shadow-[0_16px_40px_rgba(15,23,42,0.14)]">
                <div className="mb-2 grid grid-cols-2 gap-2">
                  <Select
                    value={String(calendarMonth.getMonth())}
                    onValueChange={(value) => {
                      setCalendarMonth((current) => new Date(current.getFullYear(), Number(value), 1));
                    }}
                  >
                    <SelectTrigger className="h-9 w-full border-[#dce7f7] bg-white text-xs font-semibold text-[#32518d]">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent className="max-h-64 min-w-24">
                      {MONTH_OPTIONS.map((month) => (
                        <SelectItem key={month.value} value={String(month.value)}>
                          {t(month.labelKey)}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                  <Select
                    value={String(calendarMonth.getFullYear())}
                    onValueChange={(value) => {
                      setCalendarMonth((current) => new Date(Number(value), current.getMonth(), 1));
                    }}
                  >
                    <SelectTrigger className="h-9 w-full border-[#dce7f7] bg-white text-xs font-semibold text-[#32518d]">
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent className="max-h-64 min-w-24">
                      {quickYears.map((year) => (
                        <SelectItem key={year} value={String(year)}>
                          {year}
                        </SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <Calendar
                  mode="single"
                  month={calendarMonth}
                  onMonthChange={setCalendarMonth}
                  selected={selectedDate}
                  onSelect={(value) => {
                    if (!value) return;
                    setDate(formatBusinessDate(value));
                    setCalendarMonth(value);
                    setDatePickerOpen(false);
                  }}
                  className="rounded-lg"
                />
              </PopoverContent>
            </Popover>
            {date ? (
              <Button
                type="button"
                size="icon"
                variant="outline"
                className="h-10 w-10 rounded-lg border-[#dce7f7] bg-white text-[#7890b8] hover:bg-[#f8fbff] hover:text-[#32518d]"
                aria-label={t("actions.clear")}
                onClick={() => setDate("")}
              >
                <XIcon className="size-4" />
              </Button>
            ) : null}
            <Button
              type="button"
              size="sm"
              className="h-10 rounded-lg bg-[#07459f] px-4 text-white hover:bg-[#063b88]"
              onClick={() => void fetchList(1, false)}
            >
              {t("actions.apply")}
            </Button>
          </div>
        </div>

        {loading ? (
          <div className="space-y-3">
            <Skeleton className="h-28 rounded-xl" />
            <Skeleton className="h-28 rounded-xl" />
            <Skeleton className="h-28 rounded-xl" />
          </div>
        ) : 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"
              size="sm"
              className="mt-3 bg-[#e5002c] text-white hover:bg-[#d10028]"
              onClick={() => void fetchList(1, false)}
            >
              {t("actions.retry")}
            </Button>
          </div>
        ) : items && items.length === 0 ? (
          <div className="rounded-xl border border-dashed border-[#dce7f7] bg-[#f8fbff] px-3 py-8 text-center text-sm text-slate-500">
            {t("results.empty")}
          </div>
        ) : (
          <div className="space-y-3">
            {featured ? (
              <div className="rounded-xl border border-[#e5edf8] bg-white p-3 shadow-[0_10px_28px_rgba(15,23,42,0.06)]">
                <div className="flex flex-wrap items-start justify-between gap-3 border-b border-[#edf2f9] pb-3">
                  <div className="min-w-0">
                    <p className="text-[11px] font-black uppercase tracking-normal text-[#0b56b7]">
                      {t("results.detailTitle")}
                    </p>
                    <p className="mt-1 font-mono text-lg font-black text-[#0b3f96]">
                      {featured.draw_no}
                    </p>
                    <p className="mt-1 font-mono text-xs text-slate-500">
                      {t("results.drawTime", {
                        time: formatPlayerInstant(
                          featured.draw_time_iso ?? featured.draw_time ?? null,
                        ),
                      })}
                    </p>
                  </div>
                  <Link
                    href={`/results/${encodeURIComponent(featured.draw_no)}`}
                    prefetch={false}
                    className="inline-flex h-8 shrink-0 items-center justify-center rounded-full border border-[#dce7f7] bg-white px-3 text-sm font-semibold text-[#0b56b7] transition-colors hover:bg-[#f1f6ff]"
                  >
                    {t("results.openDetail", { defaultValue: "查看详情" })}
                  </Link>
                </div>
                <div className="pt-4">
                  <TwentyThreeResultsGrid numbers={featured.results} />
                  <Link
                    href="/results/check"
                    className="mt-4 inline-flex h-10 w-full items-center justify-center rounded-xl bg-[#e5002c] px-4 text-sm font-bold text-white transition-colors hover:bg-[#d10028]"
                  >
                    {t("results.viewMyWinning")}
                  </Link>
                </div>
              </div>
            ) : null}

            {items?.slice(1).map((row) => (
              <Link
                key={row.draw_no}
                href={`/results/${encodeURIComponent(row.draw_no)}`}
                prefetch={false}
                className="block rounded-xl border border-[#e5edf8] bg-white p-3 shadow-[0_8px_24px_rgba(15,23,42,0.05)] transition-colors hover:border-[#b9ccf6]"
              >
                <div className="flex items-start justify-between gap-3">
                  <div className="min-w-0">
                    <p className="truncate font-mono text-sm font-black text-[#0b3f96]">
                      {row.draw_no}
                    </p>
                    <p className="mt-1 text-[11px] text-slate-500">
                      {formatPlayerInstant(row.draw_time_iso ?? row.draw_time ?? null)}
                    </p>
                  </div>
                  <span className="shrink-0 rounded-full bg-[#f2f6ff] px-2.5 py-1 text-xs font-bold text-[#0b56b7]">
                    {t("results.detail")}
                  </span>
                </div>

                <div className="mt-3 grid grid-cols-3 gap-2 text-center">
                  {RESULTS_TOP_PRIZE_KEYS.map((tier) => (
                    <div key={tier} className="rounded-lg border border-[#edf2f8] bg-[#f8fbff] py-2">
                      <p className="text-[11px] font-bold text-[#7890b8]">
                        {t(resultsPrizeLabelKey(tier))}
                      </p>
                      <p className="mt-1 font-mono text-lg font-black tabular-nums text-[#e5002c]">
                        {row.results[tier]}
                      </p>
                    </div>
                  ))}
                </div>
              </Link>
            ))}
            <div ref={loadMoreRef} className="min-h-1" />
            {page < lastPage ? (
              <Button
                type="button"
                variant="outline"
                className="h-10 w-full rounded-xl border-[#dce7f7] bg-white text-sm font-bold text-[#32518d] hover:bg-[#f8fbff]"
                disabled={loadingMore}
                onClick={() => void fetchList(page + 1, true)}
              >
                {loadingMore
                  ? t("actions.loading")
                  : t("actions.loadMore")}
              </Button>
            ) : items && items.length > 0 ? (
              <p className="py-2 text-center text-xs text-slate-400">
                {t("results.noMore")}
              </p>
            ) : null}
          </div>
        )}
      </div>
    </PlayerPanel>
  );
}

function buildYearOptions(month: Date): number[] {
  const currentYear = new Date().getFullYear();
  const visibleYear = month.getFullYear();
  const start = Math.min(currentYear - 10, visibleYear - 2);
  const end = Math.max(currentYear + 2, visibleYear + 2);

  return Array.from({ length: end - start + 1 }, (_, index) => start + index);
}

function parseBusinessDate(value: string): Date | undefined {
  const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
  if (!match) return undefined;

  const [, year, month, day] = match;
  return new Date(Number(year), Number(month) - 1, Number(day));
}

function formatBusinessDate(value: Date): string {
  const year = value.getFullYear();
  const month = String(value.getMonth() + 1).padStart(2, "0");
  const day = String(value.getDate()).padStart(2, "0");

  return `${year}-${month}-${day}`;
}
