"use client";

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

import {
  getSettlementBill,
  postSettlementBillAdjustment,
  postSettlementBillBadDebtWriteOff,
  postSettlementBillConfirm,
  postSettlementBillPayment,
  type RebateAllocationRow,
  type SettlementBillRow,
  type SettlementBillPaymentRow,
  type DownlineShareBreakdown,
} from "@/api/admin-agent-settlement";
import { AdminLoadingState } from "@/components/admin/admin-loading-state";
import { formatAdminMinorDecimal, parseAdminMajorToMinor, parseSignedAdminMajorToMinor } from "@/lib/money";
import { formatDashboardMoneyMinor } from "@/modules/dashboard/use-dashboard-analytics";
import {
  SettlementBillAmountBreakdown,
  SettlementBillSummaryHeader,
} from "@/modules/settlement/settlement-bill-breakdown";
import { describeBillPaymentDirection } from "@/modules/settlement/settlement-bill-display";
import { settlementBillOperableByBoundAgent } from "@/modules/settlement/settlement-bill-operable";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useConfirmAction } from "@/hooks/use-confirm-action";
import { LotteryApiBizError } from "@/types/api/errors";

type AgentBillDetailProps = {
  billId: number;
  currencyCode: string;
  canManage?: boolean;
  canFinanceAdjustments?: boolean;
  boundAgent?: { id: number } | null;
  onUpdated?: () => void;
};

export function AgentBillDetail({
  billId,
  currencyCode,
  canManage = true,
  canFinanceAdjustments = false,
  boundAgent = null,
  onUpdated,
}: AgentBillDetailProps): React.ReactElement {
  const { t } = useTranslation(["agents", "settlementCenter", "common"]);
  const [bill, setBill] = useState<SettlementBillRow | null>(null);
  const [payments, setPayments] = useState<SettlementBillPaymentRow[]>([]);
  const [rebateAllocations, setRebateAllocations] = useState<RebateAllocationRow[]>([]);
  const [downlineShares, setDownlineShares] = useState<DownlineShareBreakdown | null>(null);
  const [loading, setLoading] = useState(true);
  const [loadErr, setLoadErr] = useState<string | null>(null);
  const [payAmount, setPayAmount] = useState("");
  const [payMethod, setPayMethod] = useState("");
  const [payProof, setPayProof] = useState("");
  const [adjustAmount, setAdjustAmount] = useState("");
  const [adjustReason, setAdjustReason] = useState("");
  const [badDebtReason, setBadDebtReason] = useState("");
  const [rebateDetailsOpen, setRebateDetailsOpen] = useState(false);
  const { request: requestConfirm, ConfirmDialog, busy: confirmBusy } = useConfirmAction();

  const load = useCallback(async () => {
    setLoading(true);
    setLoadErr(null);
    try {
      const data = await getSettlementBill(billId);
      setBill(data.bill);
      setPayments(data.payments ?? []);
      setRebateAllocations(data.rebate_allocations ?? []);
      setDownlineShares(data.downline_shares ?? null);
      setPayAmount(formatAdminMinorDecimal(data.bill.unpaid_amount ?? 0, currencyCode));
    } catch (e) {
      setBill(null);
      setPayments([]);
      setRebateAllocations([]);
      setDownlineShares(null);
      setLoadErr(e instanceof LotteryApiBizError ? e.message : t("loadFailed", { ns: "common" }));
    } finally {
      setLoading(false);
    }
  }, [billId, currencyCode, t]);

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

  if (loading && !bill) {
    return <AdminLoadingState />;
  }

  if (loadErr || !bill) {
    return (
      <div className="space-y-3 py-4">
        <p className="text-sm text-destructive">{loadErr ?? t("loadFailed", { ns: "common" })}</p>
        <Button type="button" size="sm" variant="outline" onClick={() => void load()}>
          {t("retry", { ns: "common", defaultValue: "重试" })}
        </Button>
      </div>
    );
  }

  const direction = describeBillPaymentDirection(bill, t);
  const canOperateBill = canManage && settlementBillOperableByBoundAgent(bill, boundAgent);
  const locked = ["confirmed", "partial_paid", "settled", "overdue"].includes(bill.status);
  const paymentTitle = direction.ownerOwes
    ? t("settlementBills.submitReceipt", { defaultValue: "登记收款" })
    : t("settlementBills.submitPayout", { defaultValue: "登记付款" });
  const paymentSubmit = direction.ownerOwes
    ? t("settlementBills.submitReceipt", { defaultValue: "确认收款" })
    : t("settlementBills.submitPayout", { defaultValue: "确认付款" });
  const canWriteOff =
    canFinanceAdjustments &&
    bill.unpaid_amount > 0 &&
    ["confirmed", "partial_paid", "overdue"].includes(bill.status) &&
    !["adjustment", "reversal", "bad_debt"].includes(bill.bill_type);
  const rebateAllocationSummary = Object.values(
    rebateAllocations.reduce<Record<string, { key: string; label: string; amount: number; rows: number }>>(
      (acc, row) => {
        const label = row.participant_label ?? `${row.participant_type}#${row.participant_id}`;
        const key = `${row.participant_type}:${row.participant_id}:${row.allocation_rule}`;
        const current = acc[key];
        if (current) {
          current.amount += row.allocated_amount;
          current.rows += 1;
          return acc;
        }

        acc[key] = {
          key,
          label: `${label} · ${row.allocation_rule}`,
          amount: row.allocated_amount,
          rows: 1,
        };

        return acc;
      },
      {},
    ),
  ).sort((a, b) => b.amount - a.amount || a.label.localeCompare(b.label, "zh-CN"));

  const showActionError = (err: unknown, fallback: string): void => {
    toast.error(err instanceof LotteryApiBizError ? err.message : fallback);
  };

  const requestConfirmBill = (): void => {
    requestConfirm({
      title: t("settlementBills.confirmBillTitle", { defaultValue: "确认账单？" }),
      description: t("settlementBills.confirmBillDescription", {
        defaultValue: "确认后账单会进入待收付状态，请确认金额与双方无误。",
      }),
      confirmLabel: t("settlementBills.confirm", { defaultValue: "确认账单" }),
      confirmVariant: "default",
      onConfirm: async () => {
        try {
          await postSettlementBillConfirm(billId);
          await load();
          await onUpdated?.();
          toast.success(t("settlementBills.confirmed", { defaultValue: "已确认" }));
        } catch (err: unknown) {
          showActionError(
            err,
            t("settlementBills.confirmFailed", { defaultValue: "确认账单失败" }),
          );
        }
      },
    });
  };

  const requestPayment = (): void => {
    const amount = parseAdminMajorToMinor(payAmount, currencyCode);
    if (amount === null || amount <= 0) {
      toast.error(t("settlementBills.paymentAmountInvalid", { defaultValue: "请输入大于 0 的有效金额" }));
      return;
    }
    if (amount > bill.unpaid_amount) {
      toast.error(t("settlementBills.paymentAmountTooLarge", { defaultValue: "收付金额不能超过未结金额" }));
      return;
    }

    requestConfirm({
      title: t("settlementBills.paymentConfirmTitle", { defaultValue: "确认登记收付？" }),
      description: t("settlementBills.paymentConfirmDescription", {
        defaultValue: "这会写入收付记录并更新账单已付/未结金额，请确认金额与方向无误。",
      }),
      confirmLabel: paymentSubmit,
      confirmVariant: "default",
      onConfirm: async () => {
        try {
          await postSettlementBillPayment(billId, {
            amount,
            method: payMethod.trim() || undefined,
            proof: payProof.trim() || undefined,
          });
          await load();
          await onUpdated?.();
          toast.success(t("settlementBills.paid", { defaultValue: "已登记收付" }));
        } catch (err: unknown) {
          showActionError(
            err,
            t("settlementBills.paymentFailed", { defaultValue: "登记收付失败" }),
          );
        }
      },
    });
  };

  const requestBadDebtWriteOff = (): void => {
    const reason = badDebtReason.trim();
    if (!reason) {
      toast.error(t("settlementBills.badDebtReasonRequired", { defaultValue: "请填写核销原因" }));
      return;
    }

    requestConfirm({
      title: t("settlementBills.badDebtConfirmTitle", { defaultValue: "确认核销坏账？" }),
      description: t("settlementBills.badDebtConfirmDescription", {
        defaultValue: "核销会把未结金额归档为坏账记录，这类资金动作需要确认原因无误。",
      }),
      confirmLabel: t("settlementBills.confirmBadDebt", { defaultValue: "确认核销" }),
      confirmVariant: "destructive",
      onConfirm: async () => {
        try {
          await postSettlementBillBadDebtWriteOff(billId, { reason });
          await load();
          await onUpdated?.();
          toast.success(t("settlementBills.badDebtDone", { defaultValue: "已核销坏账" }));
        } catch (err: unknown) {
          showActionError(
            err,
            t("settlementBills.badDebtFailed", { defaultValue: "核销坏账失败" }),
          );
        }
      },
    });
  };

  const requestAdjustment = (): void => {
    const amount = parseSignedAdminMajorToMinor(adjustAmount, currencyCode);
    const reason = adjustReason.trim();
    if (amount === null || amount === 0) {
      toast.error(t("settlementBills.adjustmentAmountInvalid", { defaultValue: "请输入非 0 的有效金额" }));
      return;
    }
    if (!reason) {
      toast.error(t("settlementBills.adjustmentReasonRequired", { defaultValue: "请填写补差/冲正原因" }));
      return;
    }

    requestConfirm({
      title: t("settlementBills.adjustmentConfirmTitle", { defaultValue: "确认创建补差/冲正单？" }),
      description: t("settlementBills.adjustmentConfirmDescription", {
        defaultValue: "提交后会生成独立调账单，需要后续确认与收付；请确认正负方向和原因无误。",
      }),
      confirmLabel: t("settlementBills.createAdjustment", { defaultValue: "创建补差单" }),
      confirmVariant: amount < 0 ? "destructive" : "default",
      onConfirm: async () => {
        try {
          await postSettlementBillAdjustment(billId, {
            amount,
            adjustment_type: amount < 0 ? "reversal" : "adjustment",
            reason,
          });
          setAdjustAmount("");
          setAdjustReason("");
          toast.success(t("settlementBills.adjustmentCreated", { defaultValue: "已创建补差单" }));
          await onUpdated?.();
        } catch (err: unknown) {
          showActionError(
            err,
            t("settlementBills.adjustmentFailed", { defaultValue: "创建补差单失败" }),
          );
        }
      },
    });
  };

  return (
    <>
    <ConfirmDialog />
    <div className="flex flex-col gap-5 text-sm">
      <SettlementBillSummaryHeader bill={bill} currencyCode={currencyCode} />
      <SettlementBillAmountBreakdown
        bill={bill}
        currencyCode={currencyCode}
        downlineShares={downlineShares}
      />

      {payments.length > 0 ? (
        <div className="space-y-2 rounded-xl border border-border/70 p-4">
          <p className="font-medium">
            {t("settlementBills.paymentsHistory", { defaultValue: "收付记录" })}
          </p>
          <ul className="space-y-1.5 text-muted-foreground">
            {payments.map((p) => (
              <li key={p.id} className="flex justify-between gap-2">
                <span>
                  {p.method
                    ? `${p.method}`
                    : t("settlementCenter:billDisplay.payment", { defaultValue: "收付" })}
                  {p.remark ? ` · ${p.remark}` : ""}
                </span>
                <span className="shrink-0 tabular-nums">
                  {formatDashboardMoneyMinor(p.amount, currencyCode)}
                </span>
              </li>
            ))}
          </ul>
        </div>
      ) : null}

      {rebateAllocations.length > 0 ? (
          <div className="space-y-2 rounded-xl border border-border/70 bg-card p-5 shadow-sm">
            <p className="font-semibold tracking-tight">
              {t("settlementBills.rebateAllocations", { defaultValue: "回水分摊" })}
            </p>
            <p className="text-xs text-muted-foreground/80">
              {t("settlementCenter:billDisplay.rebateAllocationsHint", {
                defaultValue: "各层级代理对回水的承担明细。",
              })}
            </p>
            <div className="mt-3 space-y-3">
              <ul className="space-y-1.5 text-muted-foreground">
                {rebateAllocationSummary.map((row) => (
                  <li key={row.key} className="flex justify-between gap-2">
                    <span className="min-w-0">
                      {row.label}
                      <span className="ml-2 text-xs text-muted-foreground/60">
                        {t("common:count", { defaultValue: "{{count}} 条", count: row.rows })}
                      </span>
                    </span>
                    <span className="shrink-0 tabular-nums">
                      {formatDashboardMoneyMinor(row.amount, currencyCode)}
                    </span>
                  </li>
                ))}
              </ul>

              <button
                type="button"
                className="text-xs font-medium text-primary underline-offset-4 hover:underline"
                onClick={() => setRebateDetailsOpen((open) => !open)}
              >
                {rebateDetailsOpen
                  ? t("settlementCenter:billDisplay.hideRawRebateAllocations", {
                      defaultValue: "收起原始明细",
                    })
                  : t("settlementCenter:billDisplay.showRawRebateAllocations", {
                      defaultValue: "展开原始明细",
                    })}
              </button>

              {rebateDetailsOpen ? (
                <ul className="max-h-[280px] space-y-1.5 overflow-y-auto rounded-lg border border-dashed border-border/70 p-3 pr-2 text-muted-foreground">
                  {rebateAllocations.map((row) => (
                    <li key={row.id} className="flex justify-between gap-2">
                      <span>
                        {row.participant_label ?? `${row.participant_type}#${row.participant_id}`} ·{" "}
                        {row.allocation_rule}
                      </span>
                      <span className="shrink-0 tabular-nums">
                        {formatDashboardMoneyMinor(row.allocated_amount, currencyCode)}
                      </span>
                    </li>
                  ))}
                </ul>
              ) : null}
            </div>
          </div>
        ) : null}

      {canOperateBill && bill.status === "pending_confirm" ? (
        <div className="space-y-3 rounded-xl border border-primary/20 bg-primary/5 p-5 shadow-sm">
          <div className="space-y-1">
            <p className="font-semibold tracking-tight text-primary">
              {t("settlementBills.confirm", { defaultValue: "确认账单" })}
            </p>
            <p className="text-xs text-muted-foreground/80">
              {t("settlementCenter:billDisplay.confirmHint", {
                defaultValue: "确认后才可以登记收款或付款。",
              })}
            </p>
          </div>
          <Button
            type="button"
            className="w-full sm:w-auto sm:min-w-[10rem]"
            disabled={confirmBusy}
            onClick={requestConfirmBill}
          >
            {t("settlementBills.confirm", { defaultValue: "确认账单" })}
          </Button>
        </div>
      ) : null}

      {canOperateBill && ["confirmed", "partial_paid", "overdue"].includes(bill.status) && bill.unpaid_amount > 0 ? (
          <div className="space-y-4 rounded-xl border border-border/70 bg-card p-5 shadow-sm">
            <div className="space-y-2">
              <div className="flex flex-wrap items-center justify-between gap-2">
                <p className="font-semibold tracking-tight">{paymentTitle}</p>
                <span className="rounded-full bg-amber-500/10 px-2.5 py-0.5 text-xs font-medium text-amber-600 dark:bg-amber-500/20 dark:text-amber-400">
                  {t("settlementCenter:columns.unpaid", { defaultValue: "未结" })}{" "}
                  {formatDashboardMoneyMinor(bill.unpaid_amount, currencyCode)}
                </span>
              </div>
              <div className="flex flex-wrap items-center gap-1 text-[13px] text-muted-foreground">
                <span className="font-medium text-foreground/80">{direction.payer}</span>
                <ArrowRight className="size-3.5 shrink-0" aria-hidden />
                <span className="font-medium text-foreground/80">{direction.payee}</span>
              </div>
            </div>
            <div className="grid gap-4 mt-2">
              <div className="space-y-1.5">
                <Label className="text-muted-foreground">{t("settlementBills.paymentAmount", { defaultValue: "收付金额" })}</Label>
                <Input
                  value={payAmount}
                  onChange={(e) => setPayAmount(e.target.value)}
                  inputMode="decimal"
                  placeholder={formatAdminMinorDecimal(bill.unpaid_amount, currencyCode)}
                  className="bg-background/50 transition-colors focus:bg-background"
                />
              </div>
              <div className="space-y-1.5">
                <Label className="text-muted-foreground">{t("settlementBills.paymentMethod", { defaultValue: "收付方式" })}</Label>
                <Input
                  value={payMethod}
                  onChange={(e) => setPayMethod(e.target.value)}
                  placeholder={t("settlementBills.paymentMethodPlaceholder", {
                    defaultValue: "例如：现金 / 银行转账",
                  })}
                  className="bg-background/50 transition-colors focus:bg-background"
                />
              </div>
              <div className="space-y-1.5">
                <Label className="text-muted-foreground">{t("settlementBills.paymentProof", { defaultValue: "凭证/备注" })}</Label>
                <Input
                  value={payProof}
                  onChange={(e) => setPayProof(e.target.value)}
                  placeholder={t("settlementBills.paymentProofPlaceholder", {
                    defaultValue: "可填写流水号、截图说明或备注",
                  })}
                  className="bg-background/50 transition-colors focus:bg-background"
                />
              </div>
            </div>
            <Button
              type="button"
              className="w-full mt-2"
              disabled={confirmBusy}
              onClick={requestPayment}
            >
              {paymentSubmit}
            </Button>
          </div>
        ) : null}

      {canWriteOff ? (
          <div className="space-y-4 rounded-xl border border-destructive/20 bg-destructive/5 p-5 shadow-sm">
            <div className="space-y-1">
              <p className="font-semibold tracking-tight text-destructive">
                {t("settlementBills.badDebtWriteOff", { defaultValue: "坏账核销" })}
              </p>
              <p className="text-xs text-destructive/80">
                {t("settlementBills.badDebtHint", {
                  defaultValue: "仅在确认无法收回时使用，核销后会生成坏账记录。",
                })}
              </p>
            </div>
            <div className="space-y-1.5 mt-2">
              <Label className="text-destructive/90">{t("settlementBills.badDebtReason", { defaultValue: "核销原因" })}</Label>
              <Input
                value={badDebtReason}
                onChange={(e) => setBadDebtReason(e.target.value)}
                placeholder={t("settlementBills.badDebtReasonPlaceholder", {
                  defaultValue: "例如：客户失联、确认坏账",
                })}
                className="bg-background/50 transition-colors focus:bg-background border-destructive/30"
              />
            </div>
            <Button
              type="button"
              variant="destructive"
              className="w-full mt-2"
              disabled={confirmBusy}
              onClick={requestBadDebtWriteOff}
            >
              {t("settlementBills.confirmBadDebt", { defaultValue: "确认核销" })}
            </Button>
          </div>
        ) : null}

      {canFinanceAdjustments && locked ? (
          <div className="space-y-4 rounded-xl border border-dashed border-border/70 bg-card p-5 shadow-sm">
            <div className="space-y-1">
              <p className="font-semibold tracking-tight">
                {t("settlementBills.adjustment", { defaultValue: "补差/冲正单" })}
              </p>
              <p className="text-xs text-muted-foreground/80">
                {t("settlementBills.adjustmentHint", {
                  defaultValue: "正数表示补收，负数表示冲减；提交后会生成一张独立调账单。",
                })}
              </p>
            </div>
            <div className="space-y-1.5 mt-2">
              <Label className="text-muted-foreground">{t("settlementBills.adjustmentAmount", { defaultValue: "调整金额（可负）" })}</Label>
              <Input
                value={adjustAmount}
                onChange={(e) => setAdjustAmount(e.target.value)}
                inputMode="decimal"
                placeholder={t("settlementBills.adjustmentAmountPlaceholder", {
                  defaultValue: "例如：35.20 或 -10.00",
                })}
                className="bg-background/50 transition-colors focus:bg-background"
              />
            </div>
            <div className="space-y-1.5">
              <Label className="text-muted-foreground">{t("settlementBills.adjustmentReason", { defaultValue: "调整原因" })}</Label>
              <Input
                value={adjustReason}
                onChange={(e) => setAdjustReason(e.target.value)}
                placeholder={t("settlementBills.adjustmentReasonPlaceholder", {
                  defaultValue: "例如：人工复核补差、冲正错账",
                })}
                className="bg-background/50 transition-colors focus:bg-background"
              />
            </div>
            <Button
              type="button"
              variant="outline"
              className="w-full mt-2"
              disabled={confirmBusy}
              onClick={requestAdjustment}
            >
              {t("settlementBills.createAdjustment", { defaultValue: "创建补差单" })}
            </Button>
          </div>
        ) : null}
    </div>
    </>
  );
}
