"use client";

import { Check, Eye, HandCoins, X } from "lucide-react";
import { useCallback, useState } from "react";
import { useExportLabels } from "@/hooks/use-export-labels";
import { useTranslation } from "react-i18next";
import { useAsyncEffect } from "@/hooks/use-async-effect";
import { useTranslationRef } from "@/hooks/use-translation-ref";
import { toast } from "sonner";

import {
  getAdminSettlementBatches,
  postAdminApproveSettlementBatch,
  postAdminPayoutSettlementBatch,
  postAdminRejectSettlementBatch,
} from "@/api/admin-settlement";
import { AdminAgentFilter } from "@/components/admin/admin-agent-filter";
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 { ModuleScaffold } from "@/components/admin/module-scaffold";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
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 { Textarea } from "@/components/ui/textarea";
import { AdminLoadingState, AdminLoadingInline, AdminTableLoadingRow } from "@/components/admin/admin-loading-state";
import { useAdminCurrencyCatalog } from "@/hooks/use-admin-currency-catalog";
import { adminHasAnyPermission } from "@/lib/admin-permissions";
import { formatAdminMinorUnits } from "@/lib/money";
import { cn } from "@/lib/utils";
import { PRD_PAYOUT_MANAGE, PRD_PAYOUT_REVIEW } from "@/lib/admin-prd";
import { useAdminProfile } from "@/stores/admin-session";
import { LotteryApiBizError } from "@/types/api/errors";
import type { AdminSettlementBatchListData, AdminSettlementBatchRow } from "@/types/api/admin-settlement";

const STATUS_ALL = "__all__";
const STATUS_OPTIONS: { value: string; label: string }[] = [
  { value: STATUS_ALL, label: "statusOptions.all" },
  { value: "running", label: "statusOptions.running" },
  { value: "pending_review", label: "statusOptions.pending_review" },
  { value: "approved", label: "statusOptions.approved" },
  { value: "rejected", label: "statusOptions.rejected" },
  { value: "paid", label: "statusOptions.paid" },
  { value: "completed", label: "statusOptions.completed" },
  { value: "failed", label: "statusOptions.failed" },
];

type SettlementAction = "approve" | "reject" | "payout";

type PendingAction = {
  row: AdminSettlementBatchRow;
  action: SettlementAction;
};

function settlementStatusText(value: string, t: (key: string) => string): string {
  const option = STATUS_OPTIONS.find((item) => item.value === value);
  return option ? t(option.label) : value;
}

function settlementReviewStatusText(value: string | null, t: (key: string) => string): string {
  if (!value) return "—";
  const key = `reviewStatusOptions.${value}`;
  const translated = t(key);
  return translated === key ? value : translated;
}

export function SettlementBatchesConsole() {
  const { t } = useTranslation(["settlement", "common"]);
  const tRef = useTranslationRef(["settlement", "common"]);
  const exportLabels = useExportLabels("settlementBatches");
  const profile = useAdminProfile();
  useAdminCurrencyCatalog();
  const canReviewSettlement = adminHasAnyPermission(profile?.permissions, [PRD_PAYOUT_REVIEW]);
  const canManagePayout = adminHasAnyPermission(profile?.permissions, [PRD_PAYOUT_MANAGE]);
  const [data, setData] = useState<AdminSettlementBatchListData | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [draftDrawNo, setDraftDrawNo] = useState("");
  const [appliedDrawNo, setAppliedDrawNo] = useState("");
  const [draftStatus, setDraftStatus] = useState(STATUS_ALL);
  const [appliedStatus, setAppliedStatus] = useState(STATUS_ALL);
  const [agentNodeId, setAgentNodeId] = useState<number | undefined>(undefined);
  const [appliedAgentNodeId, setAppliedAgentNodeId] = useState<number | undefined>(undefined);
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(10);
  const [actingId, setActingId] = useState<number | null>(null);
  const [pendingAction, setPendingAction] = useState<PendingAction | null>(null);
  const [reviewRemark, setReviewRemark] = useState("");

  const load = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const d = await getAdminSettlementBatches({
        page,
        per_page: perPage,
        draw_no: appliedDrawNo.trim() || undefined,
        status:
          appliedStatus === STATUS_ALL || appliedStatus.trim() === ""
            ? undefined
            : appliedStatus.trim(),
        agent_node_id: appliedAgentNodeId,
      });
      setData(d);
    } catch (e) {
      setError(e instanceof LotteryApiBizError ? e.message : tRef.current("loadFailed"));
      setData(null);
    } finally {
      setLoading(false);
    }
  }, [page, perPage, appliedDrawNo, appliedStatus, appliedAgentNodeId]);

  useAsyncEffect(() => {
    void load();
  }, [page, perPage, appliedDrawNo, appliedStatus, appliedAgentNodeId]);

  const applyFilters = () => {
    setAppliedDrawNo(draftDrawNo);
    setAppliedStatus(draftStatus);
    setAppliedAgentNodeId(agentNodeId);
    setPage(1);
  };

  async function runBatchAction(batchId: number, label: string, action: () => Promise<unknown>): Promise<void> {
    setActingId(batchId);
    try {
      await action();
      toast.success(t("actionSuccess", { name: label }));
      setPendingAction(null);
      setReviewRemark("");
      await load();
    } catch (e) {
      toast.error(e instanceof LotteryApiBizError ? e.message : t("actionFailed", { name: label }));
    } finally {
      setActingId(null);
    }
  }

  const actionLabel = (action: SettlementAction): string => {
    if (action === "approve") {
      return t("approve");
    }
    if (action === "reject") {
      return t("reject");
    }
    return t("runPayout");
  };

  const confirmPendingAction = (): void => {
    if (!pendingAction) {
      return;
    }
    const { row, action } = pendingAction;
    const remark = reviewRemark.trim() || undefined;
    if (action === "approve") {
      void runBatchAction(row.id, actionLabel(action), () => postAdminApproveSettlementBatch(row.id, remark));
      return;
    }
    if (action === "reject") {
      void runBatchAction(row.id, actionLabel(action), () => postAdminRejectSettlementBatch(row.id, remark));
      return;
    }
    void runBatchAction(row.id, actionLabel(action), () => postAdminPayoutSettlementBatch(row.id));
  };

  const openActionDialog = (row: AdminSettlementBatchRow, action: SettlementAction): void => {
    setReviewRemark("");
    setPendingAction({ row, action });
  };

  return (
    <ModuleScaffold>
      <Card className="admin-list-card">
        <CardHeader className="admin-list-header space-y-6 pb-6">
          <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
            <CardTitle className="admin-list-title">{t("batchList")}</CardTitle>
          </div>
          <div className="admin-list-toolbar">
            <AdminAgentFilter
              id="settlement-batches-agent-filter"
              className="admin-list-field sm:w-[14rem]"
              value={agentNodeId}
              onChange={setAgentNodeId}
            />
            <div className="admin-list-field">
              <Label htmlFor="sb-draw-no" className="sm:w-10 sm:shrink-0">
                {t("drawNo")}
              </Label>
              <Input
                id="sb-draw-no"
                value={draftDrawNo}
                onChange={(e) => setDraftDrawNo(e.target.value)}
                placeholder={t("placeholderDrawNo")}
                className="w-full font-mono sm:w-[18rem] xl:w-[20rem]"
              />
            </div>
            <div className="admin-list-field">
              <Label className="sm:w-10 sm:shrink-0">{t("status")}</Label>
              <Select value={draftStatus} onValueChange={(v) => setDraftStatus(v ?? STATUS_ALL)}>
                <SelectTrigger className="w-full sm:w-40">
                  <SelectValue>{settlementStatusText(draftStatus, t)}</SelectValue>
                </SelectTrigger>
                <SelectContent>
                  {STATUS_OPTIONS.map((o) => (
                    <SelectItem key={o.value} value={o.value}>
                      {t(o.label)}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="admin-list-actions">
              <AdminTableExportButton
                tableId="settlement-batches-table"
                filename={exportLabels.filename}
              sheetName={exportLabels.sheetName}
              />
              <Button type="button" className="xl:shrink-0" onClick={applyFilters}>
                {t("apply")}
              </Button>
            </div>
          </div>
        </CardHeader>
        <CardContent className="admin-list-content pt-0">
          {error ? <p className="text-destructive text-sm">{error}</p> : null}
          <div className="admin-table-shell">
              <Table id="settlement-batches-table">
                <TableHeader>
                  <TableRow>
                    <TableHead>{t("table.id", { ns: "common" })}</TableHead>
                    <TableHead>{t("drawNo")}</TableHead>
                    <TableHead className="text-center">{t("totalBet")}</TableHead>
                    <TableHead className="text-center">{t("actualDeduct")}</TableHead>
                    <TableHead className="text-center">{t("payoutTotal")}</TableHead>
                    <TableHead className="text-center">{t("platformProfit")}</TableHead>
                    <TableHead>{t("reviewStatus")}</TableHead>
                    <TableHead>{t("status")}</TableHead>
                    <TableHead />
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {loading && !data ? <AdminTableLoadingRow colSpan={9} /> : null}
                  {(data?.items ?? []).map((row: AdminSettlementBatchRow) => (
                    <TableRow key={row.id}>
                      <TableCell className="font-mono text-xs">{row.id}</TableCell>
                      <TableCell className="font-mono text-sm">{row.draw_no ?? "—"}</TableCell>
                      <TableCell className="text-center font-mono text-xs tabular-nums">
                        {formatAdminMinorUnits(row.total_bet_amount, row.currency_code ?? "NPR")}
                      </TableCell>
                      <TableCell className="text-center font-mono text-xs tabular-nums">
                        {formatAdminMinorUnits(row.total_actual_deduct, row.currency_code ?? "NPR")}
                      </TableCell>
                      <TableCell className="text-center font-mono text-xs tabular-nums">
                        {formatAdminMinorUnits(row.total_payout_amount, row.currency_code ?? "NPR")}
                      </TableCell>
                      <TableCell
                        className={cn(
                          "text-center font-mono text-xs tabular-nums",
                          row.platform_profit < 0 ? "text-destructive" : "text-emerald-700",
                        )}
                      >
                        {formatAdminMinorUnits(row.platform_profit, row.currency_code ?? "NPR")}
                      </TableCell>
                      <TableCell>
                        {row.review_status ? (
                          <AdminStatusBadge status={row.review_status}>
                            {settlementReviewStatusText(row.review_status, t)}
                          </AdminStatusBadge>
                        ) : (
                          <span className="text-sm text-muted-foreground">—</span>
                        )}
                      </TableCell>
                      <TableCell>
                        <AdminStatusBadge status={row.status}>
                          {settlementStatusText(row.status, t)}
                        </AdminStatusBadge>
                      </TableCell>
                      <TableCell className="text-center">
                        <AdminRowActionsMenu
                          busy={actingId === row.id}
                          actions={[
                            {
                              key: "details",
                              label: t("details"),
                              icon: Eye,
                              href: `/admin/settlement-batches/${row.id}/details`,
                            },
                            {
                              key: "approve",
                              label: t("pass"),
                              icon: Check,
                              hidden: !canReviewSettlement,
                              disabled: actingId !== null || row.status !== "pending_review",
                              onClick: () => openActionDialog(row, "approve"),
                            },
                            {
                              key: "reject",
                              label: t("reject"),
                              icon: X,
                              hidden: !canReviewSettlement,
                              disabled: actingId !== null || row.status !== "pending_review",
                              onClick: () => openActionDialog(row, "reject"),
                            },
                            {
                              key: "payout",
                              label: t("payout"),
                              icon: HandCoins,
                              hidden: !canManagePayout,
                              disabled:
                                actingId !== null
                                || row.status !== "approved"
                                || row.review_status !== "approved",
                              onClick: () => openActionDialog(row, "payout"),
                            },
                          ]}
                        />
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
          {data ? (
            <AdminListPaginationFooter
              selectId="settlement-batches-per-page"
              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>
      <Dialog
        open={pendingAction !== null}
        onOpenChange={(open) => {
          if (!open && actingId === null) {
            setPendingAction(null);
            setReviewRemark("");
          }
        }}
      >
        <DialogContent>
          {pendingAction ? (
            <>
              <DialogHeader>
                <DialogTitle>{t("confirmAction", { name: actionLabel(pendingAction.action) })}</DialogTitle>
                <DialogDescription>
                  {pendingAction.action === "payout"
                    ? t("confirmPayoutDesc")
                    : t("confirmActionDesc", { drawNo: pendingAction.row.draw_no ?? "—" })}
                </DialogDescription>
              </DialogHeader>
              <div className="space-y-3">
                <p className="rounded-md border bg-muted/30 p-3 text-sm">
                  {t("confirmAmountLine", {
                    actual: formatAdminMinorUnits(
                      pendingAction.row.total_actual_deduct,
                      pendingAction.row.currency_code ?? "NPR",
                    ),
                    payout: formatAdminMinorUnits(
                      pendingAction.row.total_payout_amount,
                      pendingAction.row.currency_code ?? "NPR",
                    ),
                    profit: formatAdminMinorUnits(
                      pendingAction.row.platform_profit,
                      pendingAction.row.currency_code ?? "NPR",
                    ),
                  })}
                </p>
                {pendingAction.action !== "payout" ? (
                  <div className="space-y-2">
                    <Label htmlFor="settlement-review-remark">{t("reviewRemark")}</Label>
                    <Textarea
                      id="settlement-review-remark"
                      value={reviewRemark}
                      placeholder={t("reviewRemarkPlaceholder")}
                      onChange={(event) => setReviewRemark(event.target.value)}
                    />
                  </div>
                ) : null}
              </div>
              <DialogFooter>
                <Button
                  type="button"
                  variant="outline"
                  disabled={actingId !== null}
                  onClick={() => {
                    setPendingAction(null);
                    setReviewRemark("");
                  }}
                >
                  {t("cancel")}
                </Button>
                <Button
                  type="button"
                  variant={pendingAction.action === "reject" ? "destructive" : "default"}
                  disabled={actingId !== null}
                  onClick={confirmPendingAction}
                >
                  {t("confirm")}
                </Button>
              </DialogFooter>
            </>
          ) : null}
        </DialogContent>
      </Dialog>
    </ModuleScaffold>
  );
}
