"use client";

import { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";

import {
  getSettlementBills,
  type SettlementBillListScope,
  type SettlementBillRow,
} from "@/api/admin-agent-settlement";
import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer";
import { AdminLoadingState } from "@/components/admin/admin-loading-state";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { useAsyncEffect } from "@/hooks/use-async-effect";
import type { AgentSettlementPeriodFilter } from "@/modules/settlement/agent-settlement-period-select";
import { SettlementBillsTable } from "@/modules/settlement/settlement-bills-table";
import { settlementBillStatusLabel } from "@/modules/settlement/settlement-status-label";
import { LotteryApiBizError } from "@/types/api/errors";

type BillTypeFilter = "all" | "player" | "agent";
type BillStatusFilter = "all" | SettlementBillListScope;

type BillFilters = {
  billId: string;
  ownerKeyword: string;
  billType: BillTypeFilter;
  statusScope: BillStatusFilter;
};

function filtersForPeriod(boundAgentId: number | null): BillFilters {
  return {
    billId: "",
    ownerKeyword: "",
    billType: boundAgentId !== null ? "agent" : "all",
    statusScope: "all",
  };
}

function apiQueryFromFilters(filters: BillFilters): {
  bill_type?: string;
  scope?: SettlementBillListScope;
  bill_id?: number;
  keyword?: string;
} {
  const out: {
    bill_type?: string;
    scope?: SettlementBillListScope;
    bill_id?: number;
    keyword?: string;
  } = {};

  if (filters.billType === "player" || filters.billType === "agent") {
    out.bill_type = filters.billType;
  }
  if (filters.statusScope !== "all") {
    out.scope = filters.statusScope;
  }
  const id = Number(filters.billId.trim());
  if (filters.billId.trim() !== "" && !Number.isNaN(id) && id > 0) {
    out.bill_id = id;
  }
  const keyword = filters.ownerKeyword.trim();
  if (keyword !== "") {
    out.keyword = keyword;
  }

  return out;
}

export type SettlementMainPanelProps = {
  adminSiteId: number;
  currencyCode: string;
  periodFilter: AgentSettlementPeriodFilter;
  onOpenBillDetail: (billId: number) => void;
  refreshKey?: number;
  pendingConfirm: number;
  awaitingPayment: number;
  selectedPeriodStatus?: string | null;
  boundAgentId?: number | null;
};

export function SettlementMainPanel({
  adminSiteId,
  currencyCode,
  periodFilter,
  onOpenBillDetail,
  refreshKey = 0,
  pendingConfirm,
  awaitingPayment,
  selectedPeriodStatus,
  boundAgentId = null,
}: SettlementMainPanelProps): React.ReactElement {
  const { t } = useTranslation("settlementCenter");
  const periodId = periodFilter === "all" ? undefined : periodFilter;
  const periodOpen = selectedPeriodStatus === "open";

  const initialFilters = useMemo(() => filtersForPeriod(boundAgentId), [boundAgentId]);

  const [draft, setDraft] = useState<BillFilters>(initialFilters);
  const [applied, setApplied] = useState<BillFilters>(initialFilters);
  const [rows, setRows] = useState<SettlementBillRow[]>([]);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(20);
  const [total, setTotal] = useState(0);

  useEffect(() => {
    setDraft(initialFilters);
    setApplied(initialFilters);
    setPage(1);
  }, [initialFilters]);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const q = apiQueryFromFilters(applied);
      const data = await getSettlementBills({
        admin_site_id: adminSiteId,
        settlement_period_id: periodId,
        bill_type: q.bill_type,
        scope: q.scope,
        bill_id: q.bill_id,
        keyword: q.keyword,
        page,
        per_page: perPage,
      });
      setRows(data.items ?? []);
      setTotal(data.total ?? data.items?.length ?? 0);
    } catch (err: unknown) {
      setRows([]);
      setTotal(0);
      toast.error(
        err instanceof LotteryApiBizError
          ? err.message
          : t("errors.loadBills", { defaultValue: "账单加载失败" }),
      );
    } finally {
      setLoading(false);
    }
  }, [adminSiteId, applied, page, perPage, periodId, t]);

  useAsyncEffect(() => {
    void load();
  }, [load, refreshKey]);

  const runSearch = () => {
    setPage(1);
    setApplied({ ...draft });
  };

  const resetFilters = () => {
    setDraft(initialFilters);
    setApplied(initialFilters);
    setPage(1);
  };

  const statusOptionLabel = (value: BillStatusFilter): string => {
    if (value === "all") {
      return t("billsPanel.filterAll", { defaultValue: "全部状态" });
    }
    if (value === "pending_confirm") {
      const label = t("billsPanel.category.pendingConfirm", { defaultValue: "待确认" });
      return pendingConfirm > 0 ? `${label} (${pendingConfirm})` : label;
    }
    if (value === "awaiting_payment") {
      const label = t("billsPanel.category.awaitingPayment", { defaultValue: "待收付" });
      return awaitingPayment > 0 ? `${label} (${awaitingPayment})` : label;
    }
    if (value === "settled") {
      return settlementBillStatusLabel("settled", t);
    }
    return t("billsPanel.filterAdjustment", { defaultValue: "调账 / 冲正" });
  };

  const emptyBillMessage = useMemo((): string | undefined => {
    if (periodOpen) {
      return t("empty.billsNeedClose", {
        defaultValue: "账单在关账后生成。请返回账期列表，对本期执行「关账」后再查看。",
      });
    }
    if (applied.statusScope !== "all") {
      return t("billsPanel.emptyFiltered", {
        defaultValue: "当前筛选下暂无账单，请改为「全部状态」或重置筛选。",
      });
    }
    return t("billsPanel.emptyClosed", {
      defaultValue:
        "本期已关账但暂无账单。常见原因：账期内无信用盘玩家的已结算注单，或占成流水不在本账期时间范围内。",
    });
  }, [applied.statusScope, periodOpen, t]);

  const billTypeOptions: BillTypeFilter[] =
    boundAgentId !== null ? ["agent"] : ["all", "player", "agent"];

  const billTypeLabel = (value: BillTypeFilter): string => {
    switch (value) {
      case "player":
        return t("billsPanel.category.player", { defaultValue: "玩家账单" });
      case "agent":
        return t("billsPanel.category.agent", { defaultValue: "代理账单" });
      default:
        return t("billsPanel.filterAllTypes", { defaultValue: "全部类型" });
    }
  };

  return (
    <div className="space-y-5">
      <div className="rounded-xl border border-border/70 bg-card p-5 shadow-sm">
        <div className="grid gap-x-5 gap-y-4 sm:grid-cols-2 lg:grid-cols-4">
          <div className="grid gap-2">
            <Label htmlFor="sb-bill-id" className="text-muted-foreground">{t("billsPanel.billId", { defaultValue: "账单 ID" })}</Label>
            <Input
              id="sb-bill-id"
              inputMode="numeric"
              placeholder={t("billsPanel.optional", { defaultValue: "可选" })}
              value={draft.billId}
              onChange={(e) => setDraft((d) => ({ ...d, billId: e.target.value }))}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  runSearch();
                }
              }}
              className="bg-background/50 transition-colors focus:bg-background"
            />
          </div>
          <div className="grid gap-2">
            <Label htmlFor="sb-owner" className="text-muted-foreground">{t("billsPanel.ownerKeyword", { defaultValue: "本方 / 对方" })}</Label>
            <Input
              id="sb-owner"
              placeholder={t("billsPanel.ownerKeywordPh", { defaultValue: "玩家账号、代理名称" })}
              value={draft.ownerKeyword}
              onChange={(e) => setDraft((d) => ({ ...d, ownerKeyword: e.target.value }))}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  runSearch();
                }
              }}
              className="bg-background/50 transition-colors focus:bg-background"
            />
          </div>
          <div className="grid gap-2">
            <Label htmlFor="sb-status" className="text-muted-foreground">{t("billsPanel.status", { defaultValue: "账单状态" })}</Label>
            <Select
              modal={false}
              value={draft.statusScope}
              onValueChange={(v) =>
                setDraft((d) => ({
                  ...d,
                  statusScope: (v ?? "all") as BillStatusFilter,
                }))
              }
            >
              <SelectTrigger id="sb-status" className="w-full bg-background/50 transition-colors focus:bg-background">
                <SelectValue>{() => statusOptionLabel(draft.statusScope)}</SelectValue>
              </SelectTrigger>
              <SelectContent>
                {(
                  [
                    "all",
                    "pending_confirm",
                    "awaiting_payment",
                    "settled",
                    "adjustment",
                  ] as BillStatusFilter[]
                ).map((value) => (
                  <SelectItem key={value} value={value}>
                    {statusOptionLabel(value)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="grid gap-2">
            <Label htmlFor="sb-type" className="text-muted-foreground">{t("billsPanel.billType", { defaultValue: "账单类型" })}</Label>
            <Select
              modal={false}
              value={draft.billType}
              onValueChange={(v) =>
                setDraft((d) => ({
                  ...d,
                  billType: (v ?? "all") as BillTypeFilter,
                }))
              }
            >
              <SelectTrigger id="sb-type" className="w-full bg-background/50 transition-colors focus:bg-background">
                <SelectValue>{() => billTypeLabel(draft.billType)}</SelectValue>
              </SelectTrigger>
              <SelectContent>
                {billTypeOptions.map((value) => (
                  <SelectItem key={value} value={value}>
                    {billTypeLabel(value)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
        </div>

        <div className="mt-5 flex flex-wrap items-center gap-3">
          <Button type="button" onClick={() => runSearch()}>
            {t("billsPanel.searchBtn", { defaultValue: "搜索" })}
          </Button>
          <Button type="button" variant="outline" onClick={() => resetFilters()}>
            {t("billsPanel.reset", { defaultValue: "重置" })}
          </Button>
          <Button type="button" variant="secondary" onClick={() => void load()}>
            {t("billsPanel.refresh", { defaultValue: "刷新" })}
          </Button>
        </div>
      </div>

      {loading && rows.length === 0 ? (
        <AdminLoadingState />
      ) : (
        <>
          <SettlementBillsTable
            rows={rows}
            loading={loading}
            currencyCode={currencyCode}
            billTypeFilter={applied.billType}
            emptyMessage={emptyBillMessage}
            onOpenDetail={onOpenBillDetail}
          />
          <AdminListPaginationFooter
            selectId="settlement-bills-per-page"
            page={page}
            perPage={perPage}
            total={total}
            lastPage={Math.max(1, Math.ceil(total / Math.max(1, perPage)))}
            loading={loading}
            onPageChange={setPage}
            onPerPageChange={(next) => {
              setPerPage(next);
              setPage(1);
            }}
          />
        </>
      )}
    </div>
  );
}
