"use client";

import Link from "next/link";
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 {
  downloadAdminSettlementBatchExport,
  getAdminSettlementBatch,
  getAdminSettlementBatchDetails,
  postAdminApproveSettlementBatch,
  postAdminPayoutSettlementBatch,
  postAdminRejectSettlementBatch,
} from "@/api/admin-settlement";
import { AdminListPaginationFooter } from "@/components/admin/admin-list-pagination-footer";
import { AdminAgentFilter } from "@/components/admin/admin-agent-filter";
import { AdminAgentIdentityCells, AdminAgentIdentityHeads } from "@/components/admin/admin-agent-columns";
import { AdminPlayerIdentityCells, AdminPlayerIdentityHeads } from "@/components/admin/admin-player-identity-columns";
import { AdminStatusBadge } from "@/components/admin/admin-status-badge";
import { ModuleScaffold } from "@/components/admin/module-scaffold";
import { Button, buttonVariants } 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 { Label } from "@/components/ui/label";
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 { useAdminPlayCodeLabel } from "@/hooks/use-admin-play-type-catalog";
import { useAdminDateTimeFormatter } from "@/hooks/use-admin-datetime-formatter";
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 {
  AdminSettlementBatchDetailsData,
  AdminSettlementBatchShowData,
} from "@/types/api/admin-settlement";

type Props = {
  batchId: number;
};

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

function settlementStatusText(value: string, t: (key: string) => string): string {
  const key = `statusOptions.${value}`;
  const translated = t(key);
  return translated === key ? value : translated;
}

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 SettlementBatchDetailsConsole({ batchId }: Props) {
  const { t } = useTranslation(["settlement", "common"]);
  const tRef = useTranslationRef(["settlement", "common"]);
  const profile = useAdminProfile();
  useAdminCurrencyCatalog();
  const playCodeLabel = useAdminPlayCodeLabel();
  const canReviewSettlement = adminHasAnyPermission(profile?.permissions, [PRD_PAYOUT_REVIEW]);
  const canManagePayout = adminHasAnyPermission(profile?.permissions, [PRD_PAYOUT_MANAGE]);
  const formatDt = useAdminDateTimeFormatter();
  const [summary, setSummary] = useState<AdminSettlementBatchShowData | null>(null);
  const [details, setDetails] = useState<AdminSettlementBatchDetailsData | null>(null);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState<string | null>(null);
  const [page, setPage] = useState(1);
  const [perPage, setPerPage] = useState(10);
  const [agentNodeId, setAgentNodeId] = useState<number | undefined>(undefined);
  const [appliedAgentNodeId, setAppliedAgentNodeId] = useState<number | undefined>(undefined);
  const [acting, setActing] = useState<string | null>(null);
  const [pendingAction, setPendingAction] = useState<SettlementAction | null>(null);
  const [reviewRemark, setReviewRemark] = useState("");
  const batchCurrency = summary?.currency_code ?? "NPR";

  const load = useCallback(async () => {
    setLoading(true);
    setErr(null);
    try {
      const [s, d] = await Promise.all([
        getAdminSettlementBatch(batchId),
        getAdminSettlementBatchDetails(batchId, {
          page,
          per_page: perPage,
          agent_node_id: appliedAgentNodeId,
        }),
      ]);
      setSummary(s);
      setDetails(d);
    } catch (e) {
      setErr(e instanceof LotteryApiBizError ? e.message : tRef.current("loadFailed"));
      setSummary(null);
      setDetails(null);
    } finally {
      setLoading(false);
    }
  }, [batchId, page, perPage, appliedAgentNodeId]);

  async function runAction(label: string, action: () => Promise<unknown>): Promise<void> {
    setActing(label);
    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 {
      setActing(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 (!summary || pendingAction === null) {
      return;
    }
    const remark = reviewRemark.trim() || undefined;
    if (pendingAction === "approve") {
      void runAction(actionLabel(pendingAction), () => postAdminApproveSettlementBatch(batchId, remark));
      return;
    }
    if (pendingAction === "reject") {
      void runAction(actionLabel(pendingAction), () => postAdminRejectSettlementBatch(batchId, remark));
      return;
    }
    void runAction(actionLabel(pendingAction), () => postAdminPayoutSettlementBatch(batchId));
  };

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

  async function exportCsv(): Promise<void> {
    setActing(t("export"));
    try {
      const blob = await downloadAdminSettlementBatchExport(batchId);
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `settlement-${batchId}.csv`;
      document.body.appendChild(a);
      a.click();
      a.remove();
      URL.revokeObjectURL(url);
    } catch (e) {
      toast.error(e instanceof LotteryApiBizError ? e.message : t("exportFailed"));
    } finally {
      setActing(null);
    }
  }

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

  return (
    <ModuleScaffold>
      <div className="mb-4">
        <Link href="/admin/settlement-batches" className={cn(buttonVariants({ variant: "ghost", size: "sm" }), "px-0")}>
          ← {t("backToList")}
        </Link>
      </div>

      {err ? (
        <Card className="border-destructive/40">
          <CardHeader>
            <CardTitle className="text-base">{t("errorTitle")}</CardTitle>
          </CardHeader>
          <CardContent className="space-y-2">
            <p className="text-sm text-destructive">{err}</p>
            <Button type="button" size="sm" variant="secondary" onClick={() => void load()}>
              {t("retry")}
            </Button>
          </CardContent>
        </Card>
      ) : null}

      {summary ? (
        <Card className="mb-6">
          <CardHeader>
            <CardTitle className="font-mono text-base">{t("batchSummary", { id: summary.id })}</CardTitle>
            <p className="text-sm text-muted-foreground">
              {t("summaryMeta", {
                drawNo: summary.draw_no ?? "—",
                drawStatus: summary.draw_status ?? "—",
                version: summary.result_batch_version ?? "—",
              })}
            </p>
          </CardHeader>
          <CardContent className="grid gap-2 text-sm sm:grid-cols-2">
            <p className="flex flex-wrap items-center gap-2">
              <span className="text-muted-foreground">{t("settlementStatus")}</span>
              <AdminStatusBadge status={summary.status}>
                {settlementStatusText(summary.status, t)}
              </AdminStatusBadge>
            </p>
            <p className="flex flex-wrap items-center gap-2">
              <span className="text-muted-foreground">{t("reviewState")}</span>
              {summary.review_status ? (
                <AdminStatusBadge status={summary.review_status}>
                  {settlementReviewStatusText(summary.review_status, t)}
                </AdminStatusBadge>
              ) : (
                <span>—</span>
              )}
            </p>
            <p>
              <span className="text-muted-foreground">{t("ticketTotal")}</span>{" "}
              <span className="tabular-nums">{summary.total_ticket_count}</span>
            </p>
            <p>
              <span className="text-muted-foreground">{t("winTotal")}</span>{" "}
              <span className="tabular-nums">{summary.total_win_count}</span>
            </p>
            <p>
              <span className="text-muted-foreground">{t("totalBet")}</span>{" "}
              <span className="font-mono tabular-nums">
                {formatAdminMinorUnits(summary.total_bet_amount, summary.currency_code ?? "NPR")}
              </span>
            </p>
            <p>
              <span className="text-muted-foreground">{t("actualDeduct")}</span>{" "}
              <span className="font-mono tabular-nums">
                {formatAdminMinorUnits(summary.total_actual_deduct, summary.currency_code ?? "NPR")}
              </span>
            </p>
            <p>
              <span className="text-muted-foreground">{t("payoutAmount")}</span>{" "}
              <span className="font-mono tabular-nums">
                {formatAdminMinorUnits(summary.total_payout_amount, summary.currency_code ?? "NPR")}
              </span>
            </p>
            <p>
              <span className="text-muted-foreground">{t("jackpotPayout")}</span>{" "}
              <span className="font-mono tabular-nums">
                {formatAdminMinorUnits(summary.total_jackpot_payout_amount, summary.currency_code ?? "NPR")}
              </span>
            </p>
            <p>
              <span className="text-muted-foreground">{t("platformProfit")}</span>{" "}
              <span
                className={cn(
                  "font-mono tabular-nums",
                  summary.platform_profit < 0 ? "text-destructive" : "text-emerald-700",
                )}
              >
                {formatAdminMinorUnits(summary.platform_profit, summary.currency_code ?? "NPR")}
              </span>
            </p>
            <p>
              <span className="text-muted-foreground">{t("startedAt")}</span> {formatDt(summary.started_at)}
            </p>
            <p>
              <span className="text-muted-foreground">{t("endedAt")}</span> {formatDt(summary.finished_at)}
            </p>
            <div className="flex flex-wrap gap-2 sm:col-span-2">
              {canReviewSettlement ? (
                <Button
                  type="button"
                  size="sm"
                  variant="outline"
                  disabled={acting !== null || summary.status !== "pending_review"}
                  onClick={() => openActionDialog("approve")}
                >
                  {t("approve")}
                </Button>
              ) : null}
              {canReviewSettlement ? (
                <Button
                  type="button"
                  size="sm"
                  variant="outline"
                  disabled={acting !== null || summary.status !== "pending_review"}
                  onClick={() => openActionDialog("reject")}
                >
                  {t("reject")}
                </Button>
              ) : null}
              {canManagePayout ? (
                <Button
                  type="button"
                  size="sm"
                  disabled={
                    acting !== null
                    || summary.status !== "approved"
                    || summary.review_status !== "approved"
                  }
                  onClick={() => openActionDialog("payout")}
                >
                  {t("runPayout")}
                </Button>
              ) : null}
              <Button type="button" size="sm" variant="secondary" disabled={acting !== null} onClick={() => void exportCsv()}>
                {t("exportSettlementReport")}
              </Button>
            </div>
          </CardContent>
        </Card>
      ) : loading ? (
        <AdminLoadingState minHeight="6rem" className="py-4" label={t("loadingSummary")} />
      ) : null}

      <Card>
        <CardHeader>
          <CardTitle className="text-base">{t("detailTitle")}</CardTitle>
        </CardHeader>
        <CardContent>
          {details ? (
            <>
              <div className="mb-4 flex flex-wrap items-end gap-3">
                <AdminAgentFilter
                  id="settlement-details-agent-filter"
                  className="w-[14rem]"
                  value={agentNodeId}
                  onChange={setAgentNodeId}
                />
                <Button
                  type="button"
                  size="sm"
                  onClick={() => {
                    setAppliedAgentNodeId(agentNodeId);
                    setPage(1);
                  }}
                >
                  {t("search", { ns: "common", defaultValue: "Search" })}
                </Button>
              </div>
              <Table id={`settlement-details-table-${batchId}`}>
                <TableHeader>
                  <TableRow>
                    <TableHead>{t("ticketNo")}</TableHead>
                    <TableHead>{t("playCode")}</TableHead>
                    <AdminAgentIdentityHeads />
                    <AdminPlayerIdentityHeads />
                    <TableHead>{t("matchedTier")}</TableHead>
                    <TableHead className="text-center">{t("regularPayout")}</TableHead>
                    <TableHead className="text-center">{t("jackpot")}</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {details.items.map((r) => (
                    <TableRow key={r.id}>
                      <TableCell className="font-mono text-xs">{r.ticket_no ?? "—"}</TableCell>
                      <TableCell className="text-xs">{playCodeLabel(r.play_code)}</TableCell>
                      <AdminAgentIdentityCells row={r} />
                      <AdminPlayerIdentityCells row={r} />
                      <TableCell className="text-xs">{r.matched_prize_tier ?? "—"}</TableCell>
                      <TableCell className="text-center font-mono text-xs tabular-nums">
                        {formatAdminMinorUnits(r.win_amount, r.currency_code ?? batchCurrency)}
                      </TableCell>
                      <TableCell className="text-center font-mono text-xs tabular-nums">
                        {formatAdminMinorUnits(
                          r.jackpot_allocation_amount,
                          r.currency_code ?? batchCurrency,
                        )}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
              <AdminListPaginationFooter
                selectId="settlement-details-per-page"
                total={details.meta.total}
                page={details.meta.current_page}
                lastPage={details.meta.last_page}
                perPage={details.meta.per_page}
                loading={loading}
                onPerPageChange={(n) => {
                  setPerPage(n);
                  setPage(1);
                }}
                onPageChange={setPage}
              />
            </>
          ) : (
            <p className="text-muted-foreground text-sm">
              {loading ? (
                <AdminLoadingInline label={t("loadingDetails")} />
              ) : (
                t("states.noData", { ns: "common" })
              )}
            </p>
          )}
        </CardContent>
      </Card>
      <Dialog
        open={pendingAction !== null}
        onOpenChange={(open) => {
          if (!open && acting === null) {
            setPendingAction(null);
            setReviewRemark("");
          }
        }}
      >
        <DialogContent>
          {summary && pendingAction ? (
            <>
              <DialogHeader>
                <DialogTitle>{t("confirmAction", { name: actionLabel(pendingAction) })}</DialogTitle>
                <DialogDescription>
                  {pendingAction === "payout"
                    ? t("confirmPayoutDesc")
                    : t("confirmActionDesc", { drawNo: summary.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(summary.total_actual_deduct, summary.currency_code ?? "NPR"),
                    payout: formatAdminMinorUnits(summary.total_payout_amount, summary.currency_code ?? "NPR"),
                    profit: formatAdminMinorUnits(summary.platform_profit, summary.currency_code ?? "NPR"),
                  })}
                </p>
                {pendingAction !== "payout" ? (
                  <div className="space-y-2">
                    <Label htmlFor="settlement-detail-review-remark">{t("reviewRemark")}</Label>
                    <Textarea
                      id="settlement-detail-review-remark"
                      value={reviewRemark}
                      placeholder={t("reviewRemarkPlaceholder")}
                      onChange={(event) => setReviewRemark(event.target.value)}
                    />
                  </div>
                ) : null}
              </div>
              <DialogFooter>
                <Button
                  type="button"
                  variant="outline"
                  disabled={acting !== null}
                  onClick={() => {
                    setPendingAction(null);
                    setReviewRemark("");
                  }}
                >
                  {t("cancel")}
                </Button>
                <Button
                  type="button"
                  variant={pendingAction === "reject" ? "destructive" : "default"}
                  disabled={acting !== null}
                  onClick={confirmPendingAction}
                >
                  {t("confirm")}
                </Button>
              </DialogFooter>
            </>
          ) : null}
        </DialogContent>
      </Dialog>
    </ModuleScaffold>
  );
}
