"use client";

import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";

import {
  getAdminRiskPools,
  postAdminRiskPoolManualClose,
  postAdminRiskPoolRecover,
} from "@/api/admin-risk";
import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer";
import { AdminTableExportButton } from "@/components/admin/admin-table-export-button";
import { Button } from "@/components/ui/button";
import { buttonVariants } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { useAdminCurrencyCatalog } from "@/hooks/use-admin-currency-catalog";
import { formatAdminMinorUnits } from "@/lib/money";
import { cn } from "@/lib/utils";
import { LotteryApiBizError } from "@/types/api/errors";
import type { AdminRiskPoolListData, AdminRiskPoolRow } from "@/types/api/admin-risk";

const SORT_OPTIONS: { value: "usage_desc" | "locked_desc" | "remaining_asc" | "number_asc"; label: string }[] =
  [
    { value: "usage_desc", label: "sortUsageDesc" },
    { value: "locked_desc", label: "sortLockedDesc" },
    { value: "remaining_asc", label: "sortRemainingAsc" },
    { value: "number_asc", label: "sortNumberAsc" },
  ];

function riskSortLabel(
  value: "usage_desc" | "locked_desc" | "remaining_asc" | "number_asc",
  t: (key: string) => string,
): string {
  const option = SORT_OPTIONS.find((item) => item.value === value);
  return option ? t(option.label) : value;
}

type RiskFilter = "all" | "sold_out" | "high_risk";

type RiskPoolsConsoleProps = {
  drawId: number;
  title: string;
  soldOutOnly: boolean;
  defaultSort: "usage_desc" | "locked_desc" | "remaining_asc" | "number_asc";
  allowSortChange?: boolean;
};

export function RiskPoolsConsole({
  drawId,
  title,
  soldOutOnly,
  defaultSort,
  allowSortChange = false,
}: RiskPoolsConsoleProps) {
  const { t } = useTranslation(["risk", "common"]);
  useAdminCurrencyCatalog();
  const [sort, setSort] = useState(defaultSort);
  const [filter, setFilter] = useState<RiskFilter>(soldOutOnly ? "sold_out" : "all");
  const [number, setNumber] = useState("");
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(10);
  const [data, setData] = useState<AdminRiskPoolListData | null>(null);
  const [loading, setLoading] = useState(true);
  const [actingNumber, setActingNumber] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const d = await getAdminRiskPools(drawId, {
        page,
        per_page: perPage,
        sold_out_only: filter === "sold_out",
        high_risk_only: filter === "high_risk",
        normalized_number: number.trim(),
        sort,
      });
      setData(d);
    } catch (e) {
      const msg =
        e instanceof LotteryApiBizError ? e.message : t("loadPoolsFailed");
      setError(msg);
      setData(null);
    } finally {
      setLoading(false);
    }
  }, [drawId, filter, number, page, perPage, sort, t]);

  useEffect(() => {
    queueMicrotask(() => {
      void load();
    });
  }, [load]);

  const handleManualStatus = useCallback(
    async (row: AdminRiskPoolRow) => {
      setActingNumber(row.normalized_number);
      try {
        const updated = row.is_sold_out
          ? await postAdminRiskPoolRecover(drawId, row.normalized_number)
          : await postAdminRiskPoolManualClose(drawId, row.normalized_number);

        setData((current) => {
          if (!current) return current;

          return {
            ...current,
            items: current.items.map((item) =>
              item.normalized_number === updated.normalized_number ? updated : item,
            ),
          };
        });
        toast.success(row.is_sold_out ? t("recoverSuccess") : t("manualCloseSuccess"));
      } catch (e) {
        toast.error(e instanceof LotteryApiBizError ? e.message : t("actionFailed"));
      } finally {
        setActingNumber(null);
      }
    },
    [drawId, t],
  );

  return (
    <Card className="admin-list-card">
      <CardHeader className="admin-list-header space-y-3">
        <CardTitle className="admin-list-title">{title}</CardTitle>
        <div className="admin-list-toolbar">
          <div className="admin-list-field">
            <Label htmlFor="risk-pool-number" className="sm:w-16 sm:shrink-0">
              {t("searchNumber")}
            </Label>
            <Input
              id="risk-pool-number"
              value={number}
              maxLength={4}
              placeholder={t("searchNumberPlaceholder")}
              className="h-8 w-full font-mono sm:w-52"
              onChange={(event) => {
                setNumber(event.target.value.replace(/\D/g, "").slice(0, 4));
                setPage(1);
              }}
            />
          </div>
          <div className="admin-list-field">
            <Label className="sm:w-16 sm:shrink-0">{t("riskFilter")}</Label>
            <div className="flex flex-wrap gap-2">
              {[
                ["all", t("filterAll")],
                ["sold_out", t("filterSoldOut")],
                ["high_risk", t("filterHighRisk")],
              ].map(([value, label]) => (
                <Button
                  key={value}
                  type="button"
                  size="sm"
                  variant={filter === value ? "default" : "outline"}
                  onClick={() => {
                    setFilter(value as RiskFilter);
                    setPage(1);
                  }}
                >
                  {label}
                </Button>
              ))}
            </div>
          </div>
          {allowSortChange ? (
            <div className="admin-list-field">
              <Label htmlFor="risk-pool-sort" className="sm:w-10 sm:shrink-0">
                {t("sort")}
              </Label>
              <Select
                modal={false}
                value={sort}
                onValueChange={(v) => {
                  if (!v) return;
                  setSort(v as typeof sort);
                  setPage(1);
                }}
              >
                <SelectTrigger id="risk-pool-sort" size="sm" className="w-full sm:w-52">
                  <SelectValue>{riskSortLabel(sort, t)}</SelectValue>
                </SelectTrigger>
                <SelectContent>
                  {SORT_OPTIONS.map((o) => (
                    <SelectItem key={o.value} value={o.value}>
                      {t(o.label)}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
          ) : null}
          <div className="admin-list-actions">
            <AdminTableExportButton
              tableId={`risk-pools-table-${drawId}`}
              filename={title}
              sheetName="风险池"
            />
          </div>
        </div>
      </CardHeader>
      <CardContent className="admin-list-content">
        {error ? <p className="text-sm text-destructive">{error}</p> : null}
        {loading && !data ? (
          <p className="text-sm text-muted-foreground">{t("states.loading", { ns: "common" })}</p>
        ) : (
          <>
            <div className="admin-table-shell">
              <Table id={`risk-pools-table-${drawId}`}>
                <TableHeader>
                  <TableRow>
                    <TableHead>{t("searchNumber")}</TableHead>
                    <TableHead className="text-right">{t("capAmount")}</TableHead>
                    <TableHead className="text-right">{t("lockedAmount")}</TableHead>
                    <TableHead className="text-right">{t("remainingAmount")}</TableHead>
                    <TableHead className="text-right">{t("usageRatio")}</TableHead>
                    <TableHead>{t("poolStatus")}</TableHead>
                    <TableHead className="text-right">{t("actions")}</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {(data?.items ?? []).map((row: AdminRiskPoolRow) => {
                    const highRisk = (row.usage_ratio ?? 0) >= 0.8;
                    const acting = actingNumber === row.normalized_number;
                    const currencyCode = data?.currency_code ?? "NPR";

                    return (
                      <TableRow
                        key={row.normalized_number}
                        className={cn(
                          row.is_sold_out
                            ? "bg-red-50/90 hover:bg-red-50 dark:bg-red-950/25 dark:hover:bg-red-950/35"
                            : highRisk
                              ? "bg-orange-50/90 hover:bg-orange-50 dark:bg-orange-950/25 dark:hover:bg-orange-950/35"
                              : null,
                        )}
                      >
                        <TableCell className="font-mono font-medium">{row.normalized_number}</TableCell>
                        <TableCell className="text-right text-sm tabular-nums">
                          {formatAdminMinorUnits(row.total_cap_amount, currencyCode)}
                        </TableCell>
                        <TableCell className="text-right text-sm tabular-nums">
                          {formatAdminMinorUnits(row.locked_amount, currencyCode)}
                        </TableCell>
                        <TableCell className="text-right text-sm tabular-nums">
                          {formatAdminMinorUnits(row.remaining_amount, currencyCode)}
                        </TableCell>
                        <TableCell className="text-right text-sm tabular-nums">
                          {row.usage_ratio != null ? `${(row.usage_ratio * 100).toFixed(2)}%` : "—"}
                        </TableCell>
                        <TableCell>
                          <span
                            className={cn(
                              "inline-flex h-6 items-center rounded px-2 text-xs font-medium",
                              row.is_sold_out
                                ? "bg-red-600 text-white"
                                : highRisk
                                  ? "bg-orange-500 text-white"
                                  : "bg-muted text-muted-foreground",
                            )}
                          >
                            {row.is_sold_out ? t("soldOut") : highRisk ? t("warning") : t("normal")}
                          </span>
                        </TableCell>
                        <TableCell className="text-right">
                          <div className="flex justify-end gap-2">
                            <Button
                              type="button"
                              size="sm"
                              variant={row.is_sold_out ? "outline" : "destructive"}
                              disabled={acting}
                              onClick={() => void handleManualStatus(row)}
                            >
                              {row.is_sold_out ? t("recover") : t("close")}
                            </Button>
                            <Link
                              href={`/admin/draws/${drawId}/risk/pools/${row.normalized_number}`}
                              className={cn(
                                buttonVariants({ variant: "link", size: "sm" }),
                                "h-8 px-0",
                              )}
                            >
                              {t("view")}
                            </Link>
                          </div>
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </div>

            {data ? (
              <AdminListPaginationFooter
                selectId={`risk-pools-${drawId}-${soldOutOnly ? "so" : "all"}`}
                total={data.meta.total}
                page={data.meta.current_page}
                lastPage={data.meta.last_page}
                perPage={data.meta.per_page}
                loading={loading}
                onPerPageChange={(n) => {
                  setPerPage(n);
                  setPage(1);
                }}
                onPageChange={setPage}
              />
            ) : null}
          </>
        )}
      </CardContent>
    </Card>
  );
}
