"use client";

import { Eye, Lock, Unlock } from "lucide-react";
import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { useAsyncEffect } from "@/hooks/use-async-effect";
import { useTranslationRef } from "@/hooks/use-translation-ref";
import { toast } from "sonner";

import {
  getAdminRiskPools,
  postAdminRiskPoolManualClose,
  postAdminRiskPoolRecover,
} from "@/api/admin-risk";
import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer";
import { AdminRowActionsMenu } from "@/components/admin/admin-row-actions-menu";
import { AdminStatusBadge } from "@/components/admin/admin-status-badge";
import { AdminTableExportButton } from "@/components/admin/admin-table-export-button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { AdminTableLoadingRow } from "@/components/admin/admin-loading-state";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { adminHasAnyPermission } from "@/lib/admin-permissions";
import { PRD_DRAW_RESULT_MANAGE, PRD_RISK_MANAGE } from "@/lib/admin-prd";
import { useAdminProfile } from "@/stores/admin-session";
import { useAdminCurrencyCatalog } from "@/hooks/use-admin-currency-catalog";
import { useConfirmAction } from "@/hooks/use-confirm-action";
import { useExportLabels } from "@/hooks/use-export-labels";
import { formatAdminMinorUnits } from "@/lib/money";
import { resolveRiskPoolStatusTone } from "@/lib/admin-status-tone";
import { cn } from "@/lib/utils";
import { LotteryApiBizError } from "@/types/api/errors";
import type { RiskPoolsPageTitleKey } from "@/modules/risk/risk-display";
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;
}

export type RiskPoolListFilter = "all" | "active" | "sold_out" | "high_risk";

type RiskPoolsConsoleProps = {
  drawId: number;
  /** @deprecated 优先使用 titleKey */
  title?: string;
  titleKey?: RiskPoolsPageTitleKey;
  /** @deprecated 使用 initialFilter */
  soldOutOnly?: boolean;
  initialFilter?: RiskPoolListFilter;
  defaultSort?: "usage_desc" | "locked_desc" | "remaining_asc" | "number_asc";
  allowSortChange?: boolean;
};

function resolveInitialFilter(
  initialFilter: RiskPoolListFilter | undefined,
  soldOutOnly: boolean | undefined,
): RiskPoolListFilter {
  if (initialFilter) {
    return initialFilter;
  }
  if (soldOutOnly) {
    return "sold_out";
  }
  return "active";
}

export function RiskPoolsConsole({
  drawId,
  title,
  titleKey,
  soldOutOnly,
  initialFilter: initialFilterProp,
  defaultSort = "usage_desc",
  allowSortChange = true,
}: RiskPoolsConsoleProps) {
  const { t } = useTranslation(["risk", "common"]);
  const tRef = useTranslationRef(["risk", "common"]);
  const { request: requestConfirm, ConfirmDialog } = useConfirmAction();
  const profile = useAdminProfile();
  const canManageRiskPools = adminHasAnyPermission(profile?.permissions, [
    PRD_RISK_MANAGE,
    PRD_DRAW_RESULT_MANAGE,
  ]);
  const initialFilter = resolveInitialFilter(initialFilterProp, soldOutOnly);
  const pageTitle = titleKey ? t(titleKey) : (title ?? t("poolsTitle"));
  const exportLabels = useExportLabels("riskPools");
  useAdminCurrencyCatalog();
  const [sort, setSort] = useState(defaultSort);
  const [filter, setFilter] = useState<RiskPoolListFilter>(initialFilter);
  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",
        active_only: filter === "active" && number.trim() === "",
        normalized_number: number.trim(),
        sort,
      });
      setData(d);
    } catch (e) {
      const msg =
        e instanceof LotteryApiBizError ? e.message : tRef.current("loadPoolsFailed");
      setError(msg);
      setData(null);
    } finally {
      setLoading(false);
    }
  }, [drawId, filter, number, page, perPage, sort, tRef]);

  useAsyncEffect(() => {
    void load();
  }, [drawId, filter, number, page, perPage, sort]);

  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">
        <CardTitle className="admin-list-title">{pageTitle}</CardTitle>
      </CardHeader>
      <CardContent className="admin-list-content">
        <div className="admin-list-toolbar">
          <div className="admin-list-field">
            <Label htmlFor="risk-pool-number" className="sm:w-20 sm:shrink-0">
              {t("searchNumber")}
            </Label>
            <Input
              id="risk-pool-number"
              inputMode="numeric"
              value={number}
              maxLength={4}
              placeholder={t("searchNumberPlaceholder")}
              className="h-8 w-full font-mono sm:w-32"
              onChange={(event) => {
                setNumber(event.target.value.replace(/\D/g, "").slice(0, 4));
                setPage(1);
              }}
            />
          </div>
          <div className="admin-list-field">
            <Label className="sm:w-20 sm:shrink-0">{t("riskFilter")}</Label>
            <Select
              modal={false}
              value={filter}
              onValueChange={(v) => {
                if (!v) return;
                setFilter(v as RiskPoolListFilter);
                setPage(1);
              }}
            >
              <SelectTrigger id="risk-pool-filter" size="sm" className="h-8 w-full sm:w-40">
                <SelectValue>
                  {filter === "all"
                    ? t("filterAll")
                    : filter === "active"
                      ? t("filterActive")
                      : filter === "sold_out"
                        ? t("filterSoldOut")
                        : t("filterHighRisk")}
                </SelectValue>
              </SelectTrigger>
              <SelectContent>
                <SelectItem value="active">{t("filterActive")}</SelectItem>
                <SelectItem value="all">{t("filterAll")}</SelectItem>
                <SelectItem value="sold_out">{t("filterSoldOut")}</SelectItem>
                <SelectItem value="high_risk">{t("filterHighRisk")}</SelectItem>
              </SelectContent>
            </Select>
          </div>
          {allowSortChange ? (
            <div className="admin-list-field">
              <Label htmlFor="risk-pool-sort" className="sm:w-20 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="h-8 w-full sm:w-44">
                  <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={pageTitle ?? exportLabels.filename}
              sheetName={exportLabels.sheetName}
            />
          </div>
        </div>

        {error ? <p className="text-sm text-destructive">{error}</p> : null}
        <>
            <div className="admin-table-shell">
              <Table id={`risk-pools-table-${drawId}`}>
                <TableHeader>
                  <TableRow>
                    <TableHead>{t("searchNumber")}</TableHead>
                    <TableHead className="text-center">{t("capAmount")}</TableHead>
                    <TableHead className="text-center">{t("lockedAmount")}</TableHead>
                    <TableHead className="text-center">{t("remainingAmount")}</TableHead>
                    <TableHead className="text-center">{t("usageRatio")}</TableHead>
                    <TableHead>{t("poolStatus")}</TableHead>
                    <TableHead className="sticky right-0 z-10 text-center">{t("table.actions", { ns: "common" })}</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {loading && !data ? <AdminTableLoadingRow colSpan={7} /> : null}
                  {(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-center text-sm font-semibold">
                          {formatAdminMinorUnits(row.total_cap_amount, currencyCode)}
                        </TableCell>
                        <TableCell className="text-center text-sm font-semibold">
                          {formatAdminMinorUnits(row.locked_amount, currencyCode)}
                        </TableCell>
                        <TableCell className="text-center text-sm font-semibold">
                          {formatAdminMinorUnits(row.remaining_amount, currencyCode)}
                        </TableCell>
                        <TableCell className="text-center text-sm tabular-nums">
                          {row.usage_ratio != null ? `${(row.usage_ratio * 100).toFixed(2)}%` : "—"}
                        </TableCell>
                        <TableCell>
                          <AdminStatusBadge
                            status={row.is_sold_out ? "sold_out" : highRisk ? "warning" : "normal"}
                            tone={resolveRiskPoolStatusTone(row)}
                          >
                            {row.is_sold_out ? t("soldOut") : highRisk ? t("warning") : t("normal")}
                          </AdminStatusBadge>
                        </TableCell>
                        <TableCell className="sticky right-0 z-10 text-center">
                          <AdminRowActionsMenu
                            busy={acting}
                            actions={[
                              {
                                key: "view",
                                label: t("view"),
                                icon: Eye,
                                href: `/admin/draws/${drawId}/risk/pools/${row.normalized_number}`,
                              },
                              {
                                key: "toggle",
                                label: row.is_sold_out ? t("recover") : t("close"),
                                icon: row.is_sold_out ? Unlock : Lock,
                                destructive: !row.is_sold_out,
                                hidden: !canManageRiskPools,
                                onClick: () =>
                                  requestConfirm({
                                    title: row.is_sold_out
                                      ? t("confirm.recoverTitle")
                                      : t("confirm.closeTitle"),
                                    description: row.is_sold_out
                                      ? t("confirm.recoverDescription", {
                                          number: row.normalized_number,
                                        })
                                      : t("confirm.closeDescription", {
                                          number: row.normalized_number,
                                        }),
                                    confirmVariant: row.is_sold_out ? "default" : "destructive",
                                    onConfirm: () => handleManualStatus(row),
                                  }),
                              },
                            ]}
                          />
                        </TableCell>
                      </TableRow>
                    );
                  })}
                </TableBody>
              </Table>
            </div>

            {data ? (
              <AdminListPaginationFooter
                selectId={`risk-pools-${drawId}-${filter}`}
                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>
    <ConfirmDialog />
    </>
  );
}
