"use client";

import { useMemo, useState } from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { RefreshCw } from "lucide-react";
import { accountingApi } from "@/src/modules/accounting/services/accounting-api";
import { useTenantId } from "@/hooks/useTenantId";
import { formatMoney } from "@/lib/utils";
import {
  PageHeader,
  Button,
  Select,
  DataTable,
  EmptyState,
  LoadingState,
  ErrorState,
  Badge,
  Card,
  CardContent,
  StatCard,
} from "@/src/shared/ui";

export function LedgerPage() {
  const { tenantId } = useTenantId();
  const qc = useQueryClient();

  const periodsQ = useQuery({
    queryKey: ["accounting", tenantId, "fiscal-periods"],
    queryFn: () => accountingApi.fiscal.listPeriods(tenantId!),
    enabled: !!tenantId,
  });

  const defaultPeriod = useMemo(() => {
    const periods = periodsQ.data ?? [];
    return periods.find((p) => p.is_current)?.id ?? periods[0]?.id ?? "";
  }, [periodsQ.data]);

  const [periodId, setPeriodId] = useState("");

  const activePeriodId = periodId || defaultPeriod;

  const accountsQ = useQuery({
    queryKey: ["accounting", tenantId, "accounts"],
    queryFn: () => accountingApi.accounts.list(tenantId!),
    enabled: !!tenantId,
  });

  const balancesQ = useQuery({
    queryKey: ["accounting", tenantId, "ledger-balances", activePeriodId],
    queryFn: () => accountingApi.ledger.balances(tenantId!, activePeriodId),
    enabled: !!tenantId && !!activePeriodId,
  });

  const trialQ = useQuery({
    queryKey: ["accounting", tenantId, "trial-balance", activePeriodId],
    queryFn: () => accountingApi.ledger.trialBalance(tenantId!, activePeriodId),
    enabled: !!tenantId && !!activePeriodId,
  });

  const recalcM = useMutation({
    mutationFn: () => accountingApi.ledger.recalculate(tenantId!, activePeriodId),
    onSuccess: async (res) => {
      toast.success(`${res.recalculated_accounts} حساب محاسبه مجدد شد`);
      await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "ledger-balances", activePeriodId] });
      await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "trial-balance", activePeriodId] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const accountMap = useMemo(
    () => new Map((accountsQ.data ?? []).map((a) => [a.id, `${a.code} — ${a.name}`])),
    [accountsQ.data]
  );

  const rows = useMemo(() => {
    const balances = balancesQ.data ?? [];
    return [...balances]
      .map((b) => ({
        ...b,
        account_label: accountMap.get(b.account_id) ?? b.account_id,
      }))
      .sort((a, b) => a.account_label.localeCompare(b.account_label, "fa"));
  }, [balancesQ.data, accountMap]);

  if (!tenantId || periodsQ.isLoading) return <LoadingState />;
  if (periodsQ.error) {
    return <ErrorState message={periodsQ.error.message} onRetry={() => periodsQ.refetch()} />;
  }

  const periodName =
    periodsQ.data?.find((p) => p.id === activePeriodId)?.name ?? "—";

  return (
    <div>
      <PageHeader
        title="دفتر کل"
        description="مانده حساب‌ها، تراز آزمایشی و محاسبه مجدد — API واقعی Ledger."
        actions={
          <Button
            type="button"
            variant="outline"
            disabled={!activePeriodId || recalcM.isPending}
            onClick={() => recalcM.mutate()}
          >
            <RefreshCw className="h-4 w-4" />
            محاسبه مجدد
          </Button>
        }
      />

      <div className="mb-6 flex flex-wrap items-end gap-4">
        <div className="min-w-[220px]">
          <label className="mb-1.5 block text-sm font-medium text-secondary">دوره مالی</label>
          <Select value={activePeriodId} onChange={(e) => setPeriodId(e.target.value)}>
            <option value="">انتخاب دوره</option>
            {(periodsQ.data ?? []).map((p) => (
              <option key={p.id} value={p.id}>
                {p.name} {p.is_current ? "(جاری)" : ""}
              </option>
            ))}
          </Select>
        </div>
        {activePeriodId ? (
          <p className="text-sm text-[var(--muted)]">
            دوره انتخاب‌شده: <span className="font-medium text-secondary">{periodName}</span>
          </p>
        ) : null}
      </div>

      {!activePeriodId ? (
        <EmptyState
          title="دوره مالی انتخاب نشده"
          description="ابتدا در بخش سال و دوره مالی یک دوره ایجاد کنید."
        />
      ) : (
        <>
          <div className="mb-6 grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
            {trialQ.isLoading ? (
              <LoadingState />
            ) : trialQ.error ? (
              <ErrorState message={trialQ.error.message} onRetry={() => trialQ.refetch()} />
            ) : trialQ.data ? (
              <>
                <StatCard label="جمع بدهکار" value={formatMoney(trialQ.data.total_debit)} />
                <StatCard label="جمع بستانکار" value={formatMoney(trialQ.data.total_credit)} />
                <StatCard label="اختلاف" value={formatMoney(trialQ.data.difference)} />
                <Card>
                  <CardContent className="pt-5">
                    <p className="text-xs text-[var(--muted)]">تراز آزمایشی</p>
                    <Badge
                      className="mt-2"
                      tone={trialQ.data.is_balanced ? "success" : "danger"}
                    >
                      {trialQ.data.is_balanced ? "متوازن" : "نامتوازن"}
                    </Badge>
                  </CardContent>
                </Card>
              </>
            ) : null}
          </div>

          {balancesQ.isLoading ? (
            <LoadingState />
          ) : balancesQ.error ? (
            <ErrorState message={balancesQ.error.message} onRetry={() => balancesQ.refetch()} />
          ) : (
            <DataTable
              columns={[
                {
                  key: "account_label",
                  header: "حساب",
                  render: (r) => String(r.account_label ?? r.account_id),
                },
                {
                  key: "opening_balance",
                  header: "افتتاحیه",
                  render: (r) => formatMoney(String(r.opening_balance)),
                },
                {
                  key: "debit_total",
                  header: "گردش بدهکار",
                  render: (r) => formatMoney(String(r.debit_total)),
                },
                {
                  key: "credit_total",
                  header: "گردش بستانکار",
                  render: (r) => formatMoney(String(r.credit_total)),
                },
                {
                  key: "closing_balance",
                  header: "اختتامیه",
                  render: (r) => formatMoney(String(r.closing_balance)),
                },
                {
                  key: "current_balance",
                  header: "مانده جاری",
                  render: (r) => formatMoney(String(r.current_balance)),
                },
              ]}
              rows={rows as unknown as Record<string, unknown>[]}
              empty={
                <EmptyState
                  title="مانده‌ای ثبت نشده"
                  description="پس از ثبت اسناد، محاسبه مجدد را اجرا کنید."
                  action={
                    <Button type="button" onClick={() => recalcM.mutate()} disabled={recalcM.isPending}>
                      محاسبه مجدد
                    </Button>
                  }
                />
              }
            />
          )}
        </>
      )}
    </div>
  );
}
