"use client";

import { useMemo, useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Plus } from "lucide-react";
import { accountingApi } from "@/src/modules/accounting/services/accounting-api";
import { useTenantId } from "@/hooks/useTenantId";
import { formatMoney, parseMoneyInput, toRialInteger } from "@/lib/utils";
import {
  PageHeader,
  Button,
  Dialog,
  Input,
  DataTable,
  EmptyState,
  LoadingState,
  ErrorState,
  FormField,
  MoneyInput,
  DatePicker,
  JalaliDateText,
  Select,
  Badge,
} from "@/src/shared/ui";
import { ItemCombobox } from "@/src/modules/accounting/components/EntityCombobox";

type FormValues = {
  number: string;
  doc_date: string;
  reason: "expense" | "charity" | "consumption" | "barter";
  item_label: string;
  item_id: string;
  qty: string;
  unit_cost: string;
  warehouse_id: string;
  debit_account_id: string;
  barter_debit_account_id: string;
  barter_amount: string;
  description: string;
};

const REASON_FA: Record<string, string> = {
  expense: "هزینه",
  charity: "خیرات / اهدایی",
  consumption: "مصرف داخلی (آبدارخانه و …)",
  barter: "تهاتر / معاوضه کالا",
};

export function InventoryIssuesPage() {
  const { tenantId } = useTenantId();
  const qc = useQueryClient();
  const [open, setOpen] = useState(false);

  const listQ = useQuery({
    queryKey: ["accounting", tenantId, "ops-docs", "inventory", "issue"],
    queryFn: () => accountingApi.ops.listDocuments(tenantId!, "inventory", "issue"),
    enabled: !!tenantId,
  });
  const accountsQ = useQuery({
    queryKey: ["accounting", tenantId, "accounts"],
    queryFn: () => accountingApi.accounts.list(tenantId!),
    enabled: !!tenantId,
  });
  const warehousesQ = useQuery({
    queryKey: ["accounting", tenantId, "warehouses"],
    queryFn: () => accountingApi.ops.listWarehouses(tenantId!),
    enabled: !!tenantId,
  });
  const policyQ = useQuery({
    queryKey: ["accounting", tenantId, "posting-policy"],
    queryFn: () => accountingApi.setup.getPostingPolicy(tenantId!),
    enabled: !!tenantId,
  });

  const form = useForm<FormValues>({
    defaultValues: {
      number: "",
      doc_date: new Date().toISOString().slice(0, 10),
      reason: "expense",
      item_label: "",
      item_id: "",
      qty: "1",
      unit_cost: "0",
      warehouse_id: "",
      debit_account_id: "",
      barter_debit_account_id: "",
      barter_amount: "0",
      description: "",
    },
  });

  const reason = form.watch("reason");
  const amount = useMemo(() => {
    const q = Number(toRialInteger(form.watch("qty")) || "0");
    const c = Number(toRialInteger(form.watch("unit_cost")) || "0");
    return String(q * c);
  }, [form.watch("qty"), form.watch("unit_cost")]);

  const postable = (accountsQ.data ?? []).filter((a) => a.is_postable);
  const autoIssue = Boolean(policyQ.data?.auto_post?.inventory_issue ?? true);

  const createM = useMutation({
    mutationFn: async (d: FormValues) => {
      const amt = parseMoneyInput(amount) || "0";
      if (Number(amt) <= 0) throw new Error("مبلغ خروج باید بزرگ‌تر از صفر باشد");
      if (!d.debit_account_id) throw new Error("حساب هزینه/مقصد الزامی است");
      if (d.reason === "barter" && !d.barter_debit_account_id) {
        throw new Error("برای تهاتر، حساب کالای دریافتی را انتخاب کنید");
      }

      const doc = await accountingApi.ops.createDocument(tenantId!, {
        module: "inventory",
        doc_type: "issue",
        number: d.number?.trim() || undefined,
        doc_date: d.doc_date,
        amount: amt,
        description: d.description || REASON_FA[d.reason],
        status: "draft",
        meta_json: JSON.stringify({
          reason: d.reason,
          item_id: d.item_id,
          item_label: d.item_label,
          qty: d.qty,
          unit_cost: d.unit_cost,
          warehouse_id: d.warehouse_id || undefined,
          debit_account_id: d.debit_account_id,
          barter_debit_account_id: d.barter_debit_account_id || undefined,
          barter_amount: d.barter_amount || undefined,
        }),
      });

      if (autoIssue) {
        const posted = await accountingApi.purchaseInventory.postInventoryIssue(tenantId!, {
          source_document_id: String(doc.id),
          amount: amt,
          reason: d.reason,
          debit_account_id: d.debit_account_id,
          barter_debit_account_id: d.barter_debit_account_id || undefined,
          barter_amount:
            d.reason === "barter" ? parseMoneyInput(d.barter_amount) || amt : undefined,
        });
        await accountingApi.ops.confirmDocument(tenantId!, String(doc.id)).catch(() => null);
        return posted;
      }
      return doc;
    },
    onSuccess: async (res) => {
      const vn =
        res && typeof res === "object" && "voucher_number" in res
          ? String((res as { voucher_number?: string }).voucher_number || "")
          : "";
      toast.success(vn ? `خروج ثبت و سند ${vn} صادر شد` : "خروج کالا ثبت شد");
      setOpen(false);
      form.reset();
      await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "ops-docs", "inventory", "issue"] });
      await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "vouchers"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

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

  return (
    <div>
      <PageHeader
        title="خروج / هزینه‌کرد کالا"
        description="خروج موجودی برای هزینه، خیرات، مصرف داخلی یا تهاتر — سند حسابداری اتومات (Dr هزینه / Cr موجودی)."
        actions={
          <Button type="button" onClick={() => setOpen(true)}>
            <Plus className="h-4 w-4" />
            خروج کالای جدید
          </Button>
        }
      />

      <DataTable
        columns={[
          { key: "number", header: "شماره" },
          {
            key: "doc_date",
            header: "تاریخ",
            render: (r) => <JalaliDateText value={String(r.doc_date ?? "")} />,
          },
          {
            key: "reason",
            header: "نوع",
            render: (r) => {
              try {
                const meta = JSON.parse(String(r.meta_json || "{}")) as { reason?: string };
                return REASON_FA[meta.reason || ""] || meta.reason || "—";
              } catch {
                return "—";
              }
            },
          },
          {
            key: "amount",
            header: "مبلغ",
            render: (r) => formatMoney(String(r.amount ?? "0")),
          },
          {
            key: "status",
            header: "وضعیت",
            render: (r) => <Badge tone={r.status === "posted" || r.status === "confirmed" ? "success" : "default"}>{String(r.status)}</Badge>,
          },
          { key: "description", header: "شرح" },
        ]}
        rows={(listQ.data ?? []) as unknown as Record<string, unknown>[]}
        empty={<EmptyState title="خروجی ثبت نشده" />}
      />

      <Dialog open={open} onClose={() => setOpen(false)} title="خروج / هزینه‌کرد کالا">
        <form className="grid gap-3 sm:grid-cols-2" onSubmit={form.handleSubmit((d) => createM.mutate(d))}>
          <FormField label="نوع خروج">
            <Select
              value={reason}
              onChange={(e) => form.setValue("reason", e.target.value as FormValues["reason"])}
            >
              <option value="expense">هزینه کردن کالا</option>
              <option value="charity">خیرات / اهدایی (بدون دریافت وجه)</option>
              <option value="consumption">مصرف داخلی (آبدارخانه و …)</option>
              <option value="barter">تهاتر — کالا می‌دهم، چیز دیگری می‌گیرم</option>
            </Select>
          </FormField>
          <FormField label="تاریخ">
            <Controller
              control={form.control}
              name="doc_date"
              render={({ field }) => (
                <DatePicker value={field.value} onChange={field.onChange} onBlur={field.onBlur} name={field.name} />
              )}
            />
          </FormField>
          <div className="sm:col-span-2">
            <FormField label="کالای خروجی" hint="کالایی که از انبار خارج می‌شود">
              <ItemCombobox
                valueLabel={form.watch("item_label") || undefined}
                onSelect={(item) => {
                  form.setValue("item_id", item.id);
                  form.setValue("item_label", `${item.code} — ${item.name}`);
                  form.setValue("unit_cost", parseMoneyInput(item.unit_cost) || "0");
                }}
                onClear={() => {
                  form.setValue("item_id", "");
                  form.setValue("item_label", "");
                }}
              />
            </FormField>
          </div>
          <FormField label="تعداد">
            <Input {...form.register("qty", { required: true })} />
          </FormField>
          <FormField label="بهای واحد">
            <MoneyInput {...form.register("unit_cost", { required: true })} />
          </FormField>
          <FormField label="جمع مبلغ">
            <Input value={formatMoney(amount)} readOnly dir="ltr" />
          </FormField>
          <FormField label="انبار مبدأ">
            <Select {...form.register("warehouse_id")}>
              <option value="">انتخاب…</option>
              {(warehousesQ.data ?? []).map((w) => (
                <option key={w.id} value={w.id}>
                  {w.code} — {w.name}
                </option>
              ))}
            </Select>
          </FormField>
          <div className="sm:col-span-2">
            <FormField
              label={
                reason === "charity"
                  ? "حساب هزینه خیرات / اهدایی"
                  : reason === "consumption"
                    ? "حساب هزینه مصرف (مثلاً آبدارخانه)"
                    : reason === "barter"
                      ? "حساب مابه‌التفاوت (اگر مبلغ‌ها برابر نباشند)"
                      : "حساب هزینه مقصد"
              }
              hint="بدهکار سند اتومات — موجودی بستانکار می‌شود"
            >
              <Select {...form.register("debit_account_id", { required: true })}>
                <option value="">انتخاب حساب…</option>
                {postable.map((a) => (
                  <option key={a.id} value={a.id}>
                    {a.code} — {a.name}
                  </option>
                ))}
              </Select>
            </FormField>
          </div>
          {reason === "barter" ? (
            <>
              <div className="sm:col-span-2">
                <FormField
                  label="حساب کالای دریافتی"
                  hint="مثلاً موجودی چای / ملزومات آبدارخانه که در ازای کالای خروجی می‌گیرید"
                >
                  <Select {...form.register("barter_debit_account_id", { required: true })}>
                    <option value="">انتخاب حساب…</option>
                    {postable.map((a) => (
                      <option key={a.id} value={a.id}>
                        {a.code} — {a.name}
                      </option>
                    ))}
                  </Select>
                </FormField>
              </div>
              <FormField label="ارزش کالای دریافتی">
                <MoneyInput {...form.register("barter_amount")} />
              </FormField>
            </>
          ) : null}
          <div className="sm:col-span-2">
            <FormField label="توضیح">
              <Input
                placeholder="مثال: اهدا به خیریه / مصرف آبدارخانه در ازای چای"
                {...form.register("description")}
              />
            </FormField>
          </div>
          <p className="sm:col-span-2 text-xs text-[var(--muted)]">
            {autoIssue
              ? "با ذخیره، سند حسابداری خودکار از Posting Engine صادر می‌شود."
              : "ثبت خودکار خاموش است — فقط سند عملیاتی ذخیره می‌شود (تنظیمات → اسناد اتوماتیک)."}
          </p>
          <div className="flex justify-end gap-2 sm:col-span-2">
            <Button type="button" variant="outline" onClick={() => setOpen(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={createM.isPending}>
              ذخیره و صدور سند
            </Button>
          </div>
        </form>
      </Dialog>
    </div>
  );
}
