"use client";

import { Plus } from "lucide-react";
import { useEffect, useMemo, useState, type ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";

import {
  getSettlementPeriodOpenHints,
  postSettlementPeriod,
  postSettlementPeriodClose,
  type SettlementPeriodCloseResult,
  type SettlementPeriodOpenHints,
  type SettlementPeriodRow,
} from "@/api/admin-agent-settlement";
import { AdminDateRangeField } from "@/components/admin/admin-date-range-field";
import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer";
import { AdminPageCard } from "@/components/admin/admin-page-card";
import { SettlementPeriodsTable } from "@/modules/settlement/settlement-periods-table";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import {
  formatSettlementPeriodSpan,
  isSettlementLocalDateRangeValid,
  localDateRangeToUtcPeriodBounds,
  settlementRangeOverlapsOccupiedDates,
  utcStorageDateToLocalFormYmd,
  utcStorageDatesToLocalMarks,
} from "@/lib/agent-settlement-period-range";
import { settlementPeriodStatusLabel } from "@/modules/settlement/settlement-status-label";
import { LotteryApiBizError } from "@/types/api/errors";

type PeriodStatusFilter = "all" | "open" | "closed" | "completed";

const STATUS_FILTER_OPTIONS: PeriodStatusFilter[] = ["all", "open", "closed", "completed"];

type SettlementPeriodWorkbenchProps = {
  adminSiteId: number;
  currencyCode: string;
  canManage: boolean;
  periods: SettlementPeriodRow[];
  headerActions?: ReactNode;
  onViewDetail: (periodId: number) => void;
  onReloadPeriods: () => Promise<SettlementPeriodRow[]>;
  onPeriodOpened?: (periodId: number) => void;
  onPeriodClosed?: (result: SettlementPeriodCloseResult) => void;
};

export function SettlementPeriodWorkbench({
  adminSiteId,
  currencyCode,
  canManage,
  periods,
  headerActions,
  onViewDetail,
  onReloadPeriods,
  onPeriodOpened,
  onPeriodClosed,
}: SettlementPeriodWorkbenchProps): React.ReactElement {
  const { t } = useTranslation(["settlementCenter", "agents", "common"]);
  const [draftStatus, setDraftStatus] = useState<PeriodStatusFilter>("all");
  const [appliedStatus, setAppliedStatus] = useState<PeriodStatusFilter>("all");
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(10);
  const [openDialogOpen, setOpenDialogOpen] = useState(false);
  const [customStart, setCustomStart] = useState("");
  const [customEnd, setCustomEnd] = useState("");
  const [openHints, setOpenHints] = useState<SettlementPeriodOpenHints | null>(null);
  const [hintsLoading, setHintsLoading] = useState(false);
  const [busy, setBusy] = useState(false);
  const [reloading, setReloading] = useState(false);
  const [closeDialogOpen, setCloseDialogOpen] = useState(false);
  const [closeTarget, setCloseTarget] = useState<SettlementPeriodRow | null>(null);

  const openPeriod = useMemo(
    () => periods.find((row) => row.status === "open") ?? null,
    [periods],
  );

  const filteredPeriods = useMemo(() => {
    let list = [...periods];
    if (appliedStatus !== "all") {
      list = list.filter((row) => row.status === appliedStatus);
    }
    return list.sort((a, b) => b.id - a.id);
  }, [periods, appliedStatus]);

  const lastPage = Math.max(1, Math.ceil(filteredPeriods.length / perPage));

  const pagedPeriods = useMemo(() => {
    const start = (page - 1) * perPage;
    return filteredPeriods.slice(start, start + perPage);
  }, [filteredPeriods, page, perPage]);

  useEffect(() => {
    setPage(1);
  }, [appliedStatus, perPage]);

  useEffect(() => {
    if (page > lastPage) {
      setPage(lastPage);
    }
  }, [page, lastPage]);

  const calendarMarkers = useMemo(() => {
    if (openHints === null) {
      return undefined;
    }
    return {
      occupiedPeriod: utcStorageDatesToLocalMarks(openHints.occupied_period_dates),
      pendingActivity: utcStorageDatesToLocalMarks(openHints.pending_activity_dates),
      unpaidBill: utcStorageDatesToLocalMarks(openHints.unpaid_bill_dates),
    };
  }, [openHints]);

  const occupiedLocalDates = useMemo(
    () => utcStorageDatesToLocalMarks(openHints?.occupied_period_dates ?? []),
    [openHints],
  );

  const selectedRangeOverlapsOccupied = useMemo(() => {
    if (!customStart.trim() || !customEnd.trim()) {
      return false;
    }
    return settlementRangeOverlapsOccupiedDates(
      customStart.trim(),
      customEnd.trim(),
      occupiedLocalDates,
    );
  }, [customEnd, customStart, occupiedLocalDates]);

  const statusFilterLabel = (value: PeriodStatusFilter): string => {
    if (value === "all") {
      return t("filters.statusAll", { defaultValue: "全部" });
    }
    return settlementPeriodStatusLabel(value, t);
  };

  async function openWithRange(startYmd: string, endYmd: string): Promise<void> {
    if (!canManage) {
      return;
    }
    if (!isSettlementLocalDateRangeValid(startYmd, endYmd)) {
      toast.error(
        t("agents:settlementPeriods.invalidRange", {
          defaultValue: "结束日期不能早于开始日期",
        }),
      );
      return;
    }
    if (settlementRangeOverlapsOccupiedDates(startYmd, endYmd, occupiedLocalDates)) {
      toast.error(
        t("agents:settlementPeriods.overlapsOccupied", {
          defaultValue: "所选范围与已有账期重叠，请避开灰色删除线的日期。",
        }),
      );
      return;
    }
    const bounds = localDateRangeToUtcPeriodBounds(startYmd, endYmd);
    setBusy(true);
    try {
      const row = await postSettlementPeriod({
        admin_site_id: adminSiteId,
        period_start: bounds.period_start,
        period_end: bounds.period_end,
      });
      await onReloadPeriods();
      onPeriodOpened?.(row.id);
      setOpenDialogOpen(false);
      setCustomStart("");
      setCustomEnd("");
      setOpenHints(null);
      toast.success(t("agents:settlementPeriods.opened", { defaultValue: "账期已开启" }));
    } catch (err: unknown) {
      toast.error(
        err instanceof LotteryApiBizError
          ? err.message
          : t("agents:settlementPeriods.openFailed", { defaultValue: "开账失败" }),
      );
    } finally {
      setBusy(false);
    }
  }

  async function openCustom(): Promise<void> {
    if (!customStart.trim() || !customEnd.trim()) {
      toast.error(t("agents:settlementPeriods.datesRequired", { defaultValue: "请填写账期起止" }));
      return;
    }
    await openWithRange(customStart.trim(), customEnd.trim());
  }

  async function loadOpenHints(): Promise<void> {
    setHintsLoading(true);
    try {
      const hints = await getSettlementPeriodOpenHints({ admin_site_id: adminSiteId });
      setOpenHints(hints);
      setCustomStart("");
      setCustomEnd("");
      if (hints.suggested_start && hints.suggested_end) {
        const from = utcStorageDateToLocalFormYmd(hints.suggested_start);
        const to = utcStorageDateToLocalFormYmd(hints.suggested_end);
        const occupied = utcStorageDatesToLocalMarks(hints.occupied_period_dates);
        if (!settlementRangeOverlapsOccupiedDates(from, to, occupied)) {
          setCustomStart(from);
          setCustomEnd(to);
        }
      }
    } catch (err: unknown) {
      setOpenHints(null);
      toast.error(
        err instanceof LotteryApiBizError
          ? err.message
          : t("agents:settlementPeriods.hintsFailed", { defaultValue: "无法加载开账建议" }),
      );
    } finally {
      setHintsLoading(false);
    }
  }

  function handleOpenDialog(open: boolean): void {
    setOpenDialogOpen(open);
    if (open) {
      void loadOpenHints();
      return;
    }
    setCustomStart("");
    setCustomEnd("");
    setOpenHints(null);
  }

  function requestClose(row: SettlementPeriodRow): void {
    setCloseTarget(row);
    setCloseDialogOpen(true);
  }

  async function confirmClose(): Promise<void> {
    if (!closeTarget) {
      return;
    }
    setBusy(true);
    try {
      const result = await postSettlementPeriodClose(closeTarget.id);
      const items = await onReloadPeriods();
      setCloseDialogOpen(false);
      setCloseTarget(null);
      onPeriodClosed?.(result);
      const stillThere = items.find((row) => row.id === closeTarget.id);
      if (stillThere?.status === "closed") {
        toast.success(t("agents:settlementPeriods.closed", { defaultValue: "账期已关账，账单已生成" }));
      }
    } catch (err: unknown) {
      toast.error(
        err instanceof LotteryApiBizError
          ? err.message
          : t("agents:settlementPeriods.closeFailed", { defaultValue: "关账失败" }),
      );
    } finally {
      setBusy(false);
    }
  }

  async function handleRefresh(): Promise<void> {
    setReloading(true);
    try {
      await onReloadPeriods();
    } finally {
      setReloading(false);
    }
  }

  function applyFilters(): void {
    setAppliedStatus(draftStatus);
    setPage(1);
  }

  function resetFilters(): void {
    setDraftStatus("all");
    setAppliedStatus("all");
    setPage(1);
  }

  const shareCount = closeTarget?.pipeline?.share_ledger_count ?? 0;
  const unsettledCount = closeTarget?.pipeline?.unsettled_ticket_count ?? 0;

  const cardDescription = canManage
    ? t("subtitle", { defaultValue: "账期关账、账单确认与收付登记" })
    : t("periodTable.readOnlyHint", {
        defaultValue: "绑定代理账号不可开/关账期，仅可查看与收付。",
      });

  const openPeriodHiddenByFilter =
    openPeriod !== null &&
    appliedStatus !== "all" &&
    appliedStatus !== "open" &&
    !filteredPeriods.some((row) => row.id === openPeriod.id);

  const tableEmptyMessage = useMemo(() => {
    if (periods.length === 0) {
      if (!canManage) {
        return t("periodTable.emptyReadOnly", { defaultValue: "暂无账期记录。" });
      }
      return t("periodTable.emptyOpenHint", {
        defaultValue: "暂无账期，请点击工具栏「开账」创建。",
      });
    }
    if (openPeriodHiddenByFilter) {
      return t("periodTable.emptyFilteredOpen", {
        defaultValue: "当前筛选未包含进行中的账期，请选「全部」或「进行中」。",
      });
    }
    return t("periodTable.emptyFiltered", { defaultValue: "筛选结果为空，请重置筛选。" });
  }, [canManage, openPeriodHiddenByFilter, periods.length, t]);

  return (
    <>
      <AdminPageCard
        title={t("periodTable.title", { defaultValue: "账期管理" })}
        description={cardDescription}
        actions={headerActions}
      >
        <div className="admin-list-toolbar">
          <div className="admin-list-field">
            <Label htmlFor="sp-status-filter" className="sm:shrink-0">
              {t("periodTable.statusFilter", { defaultValue: "状态" })}
            </Label>
            <Select
              modal={false}
              value={draftStatus}
              onValueChange={(v) => setDraftStatus((v ?? "all") as PeriodStatusFilter)}
            >
              <SelectTrigger id="sp-status-filter" className="h-9 w-full sm:w-40">
                <SelectValue>{() => statusFilterLabel(draftStatus)}</SelectValue>
              </SelectTrigger>
              <SelectContent>
                {STATUS_FILTER_OPTIONS.map((value) => (
                  <SelectItem key={value} value={value}>
                    {statusFilterLabel(value)}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div className="admin-list-actions">
            {canManage && openPeriod ? (
              <Button
                type="button"
                size="sm"
                disabled={busy}
                onClick={() => requestClose(openPeriod)}
              >
                {t("periodTable.close", { defaultValue: "关账" })}
              </Button>
            ) : null}
            {canManage && !openPeriod ? (
              <Button
                type="button"
                size="sm"
                disabled={busy}
                onClick={() => handleOpenDialog(true)}
              >
                <Plus className="size-4" aria-hidden />
                {t("period.openBtn", { defaultValue: "开账" })}
              </Button>
            ) : null}
            <Button type="button" size="sm" onClick={() => applyFilters()}>
              {t("ledgerPanel.searchBtn", { defaultValue: "搜索" })}
            </Button>
            <Button type="button" size="sm" variant="secondary" onClick={() => resetFilters()}>
              {t("ledgerPanel.reset", { defaultValue: "重置筛选" })}
            </Button>
            <Button
              type="button"
              size="sm"
              variant="secondary"
              disabled={reloading}
              onClick={() => void handleRefresh()}
            >
              {t("ledgerPanel.refresh", { defaultValue: "刷新当前页" })}
            </Button>
          </div>
        </div>

        {canManage && openPeriod ? (
          <div className="flex flex-col gap-2 rounded-md border border-amber-200/80 bg-amber-50/60 px-3 py-2 text-sm text-amber-950 sm:flex-row sm:items-center sm:justify-between dark:border-amber-900/50 dark:bg-amber-950/30 dark:text-amber-100">
            <p>
              {t("periodTable.hasOpen", {
                defaultValue: "已有进行中账期 {{range}}，须先关账才能开新期。",
                range: formatSettlementPeriodSpan(openPeriod.period_start, openPeriod.period_end),
              })}
            </p>
            <Button
              type="button"
              size="sm"
              variant="secondary"
              className="shrink-0"
              disabled={busy}
              onClick={() => requestClose(openPeriod)}
            >
              {t("periodTable.closeNow", { defaultValue: "立即关账" })}
            </Button>
          </div>
        ) : null}

        <SettlementPeriodsTable
          periods={pagedPeriods}
          loading={reloading}
          canManage={canManage}
          busy={busy}
          currencyCode={currencyCode}
          emptyMessage={tableEmptyMessage}
          onViewDetail={onViewDetail}
          onRequestClose={requestClose}
        />

        <AdminListPaginationFooter
          selectId="settlement-periods-per-page"
          total={filteredPeriods.length}
          page={page}
          lastPage={lastPage}
          perPage={perPage}
          loading={reloading}
          onPerPageChange={(next) => {
            setPerPage(next);
            setPage(1);
          }}
          onPageChange={setPage}
        />
      </AdminPageCard>

      <Dialog open={openDialogOpen} onOpenChange={handleOpenDialog}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{t("period.openTitle", { defaultValue: "开账" })}</DialogTitle>
            <DialogDescription>
              {t("agents:settlementPeriods.openDesc", {
                defaultValue:
                  "选择账期起止日期；灰色删除线为已有账期不可再开，琥珀点为待入账，右上角红点为未结清。",
              })}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-3">
            <AdminDateRangeField
              id="sp-dialog-range"
              label={t("agents:settlementPeriods.rangeLabel", { defaultValue: "账期范围" })}
              from={customStart}
              to={customEnd}
              disabled={hintsLoading || busy}
              calendarMarkers={calendarMarkers}
              rangeHint={t("agents:settlementPeriods.rangeHint", {
                defaultValue: "先选开始日期，再选结束日期；单日账期可点同一天两次。",
              })}
              onRangeChange={({ from, to }) => {
                setCustomStart(from);
                setCustomEnd(to);
              }}
            />
            <div className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground">
              <span className="inline-flex items-center gap-1.5">
                <span
                  className="inline-block size-3 rounded bg-muted ring-1 ring-border line-through"
                  aria-hidden
                />
                {t("agents:settlementPeriods.markerOccupied", { defaultValue: "已有账期" })}
              </span>
              <span className="inline-flex items-center gap-1.5">
                <span
                  className="inline-block size-1.5 rounded-full bg-amber-500"
                  aria-hidden
                />
                {t("agents:settlementPeriods.markerPending", { defaultValue: "待入账流水" })}
              </span>
              <span className="inline-flex items-center gap-1.5">
                <span
                  className="relative inline-block size-3 rounded ring-1 ring-border"
                  aria-hidden
                >
                  <span className="absolute top-0 right-0 size-1.5 rounded-full bg-rose-500" />
                </span>
                {t("agents:settlementPeriods.markerUnpaid", { defaultValue: "未结清账期" })}
              </span>
            </div>
            {selectedRangeOverlapsOccupied ? (
              <p className="text-destructive text-xs">
                {t("agents:settlementPeriods.overlapsOccupied", {
                  defaultValue: "所选范围与已有账期重叠，请避开灰色删除线的日期。",
                })}
              </p>
            ) : null}
          </div>
          <DialogFooter>
            <Button
              type="button"
              variant="outline"
              disabled={busy || hintsLoading}
              onClick={() => handleOpenDialog(false)}
            >
              {t("common:cancel", { defaultValue: "取消" })}
            </Button>
            <Button
              type="button"
              disabled={busy || hintsLoading || selectedRangeOverlapsOccupied}
              onClick={() => void openCustom()}
            >
              {t("period.openBtn", { defaultValue: "开账" })}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog
        open={closeDialogOpen}
        onOpenChange={(open) => {
          setCloseDialogOpen(open);
          if (!open) {
            setCloseTarget(null);
          }
        }}
      >
        <DialogContent>
          <DialogHeader>
            <DialogTitle>{t("period.closeDialogTitle", { defaultValue: "确认关账" })}</DialogTitle>
            <DialogDescription>
              {closeTarget
                ? t("period.closeDialogDesc", {
                    defaultValue: "将汇总 {{range}} 内的流水并生成账单。",
                    range: formatSettlementPeriodSpan(
                      closeTarget.period_start,
                      closeTarget.period_end,
                    ),
                  })
                : null}
            </DialogDescription>
          </DialogHeader>
          {closeTarget ? (
            <ul className="list-inside list-disc space-y-1 text-sm text-muted-foreground">
              <li>
                {shareCount > 0
                  ? t("period.closeDialogShare", {
                      defaultValue: "流水 {{count}} 笔",
                      count: shareCount,
                    })
                  : t("period.closeDialogEmpty", {
                      defaultValue: "本期暂无占成流水，关账后不会生成账单。",
                    })}
              </li>
              {unsettledCount > 0 ? (
                <li className="text-amber-800">
                  {t("period.closeDialogUnsettled", {
                    defaultValue: "仍有 {{count}} 笔注单未结算",
                    count: unsettledCount,
                  })}
                </li>
              ) : null}
              <li>
                {t("period.closeDialogIrreversible", {
                  defaultValue: "关账后不可撤销，差错请通过调账或冲正处理。",
                })}
              </li>
            </ul>
          ) : null}
          <DialogFooter>
            <Button type="button" variant="outline" disabled={busy} onClick={() => setCloseDialogOpen(false)}>
              {t("common:cancel", { defaultValue: "取消" })}
            </Button>
            <Button type="button" disabled={busy} onClick={() => void confirmClose()}>
              {t("period.closeDialogConfirm", { defaultValue: "确认关账" })}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
