"use client";

import { useState } from "react";
import { Controller, useForm } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Eye, Pencil, Plus } 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,
  Dialog,
  Drawer,
  Input,
  DataTable,
  EmptyState,
  LoadingState,
  ErrorState,
  Badge,
  FormField,
  MoneyInput,
  Checkbox,
  DatePicker,
  JalaliDateText,
  StatCard,
} from "@/src/shared/ui";

const createSchema = z.object({
  code: z.string().optional(),
  name: z.string().min(1, "نام الزامی است"),
  credit_limit: z.string().optional(),
});

const editSchema = z.object({
  name: z.string().min(1, "نام الزامی است"),
  credit_limit: z.string().optional(),
  is_active: z.boolean(),
});

const invoiceSchema = z.object({
  invoice_number: z.string().optional(),
  invoice_date: z.string().min(1, "تاریخ الزامی است"),
  due_date: z.string().optional(),
  total_amount: z.string().min(1, "مبلغ الزامی است"),
});

type CustomerRow = {
  id: string;
  code: string;
  name: string;
  outstanding_balance: string;
  is_active: boolean;
};

export function CustomersPage() {
  const { tenantId } = useTenantId();
  const qc = useQueryClient();
  const [createOpen, setCreateOpen] = useState(false);
  const [editCustomer, setEditCustomer] = useState<CustomerRow | null>(null);
  const [detailCustomer, setDetailCustomer] = useState<CustomerRow | null>(null);
  const [invoiceOpen, setInvoiceOpen] = useState(false);

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

  const agingQ = useQuery({
    queryKey: ["accounting", tenantId, "customer-aging", detailCustomer?.id],
    queryFn: () => accountingApi.customers.aging(tenantId!, detailCustomer!.id),
    enabled: !!tenantId && !!detailCustomer,
  });

  const invoicesQ = useQuery({
    queryKey: ["accounting", tenantId, "customer-invoices", detailCustomer?.id],
    queryFn: () => accountingApi.customers.listInvoices(tenantId!, detailCustomer!.id),
    enabled: !!tenantId && !!detailCustomer,
  });

  const createForm = useForm<z.infer<typeof createSchema>>({
    resolver: zodResolver(createSchema),
    defaultValues: { code: "", name: "", credit_limit: "" },
  });

  const editForm = useForm<z.infer<typeof editSchema>>({
    resolver: zodResolver(editSchema),
    defaultValues: { name: "", credit_limit: "", is_active: true },
  });

  const invoiceForm = useForm<z.infer<typeof invoiceSchema>>({
    resolver: zodResolver(invoiceSchema),
    defaultValues: { invoice_number: "", invoice_date: "", due_date: "", total_amount: "" },
  });

  const invalidateCustomers = () =>
    qc.invalidateQueries({ queryKey: ["accounting", tenantId, "customers"] });
  const invalidateInvoices = () =>
    qc.invalidateQueries({ queryKey: ["accounting", tenantId, "customer-invoices"] });

  const createM = useMutation({
    mutationFn: (d: z.infer<typeof createSchema>) =>
      accountingApi.customers.create(tenantId!, {
        code: d.code?.trim() || undefined,
        name: d.name,
        credit_limit: d.credit_limit || undefined,
      }),
    onSuccess: async () => {
      toast.success("مشتری ایجاد شد");
      setCreateOpen(false);
      createForm.reset();
      await invalidateCustomers();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const updateM = useMutation({
    mutationFn: (d: z.infer<typeof editSchema>) =>
      accountingApi.customers.update(tenantId!, editCustomer!.id, {
        name: d.name,
        credit_limit: d.credit_limit || null,
        is_active: d.is_active,
      }),
    onSuccess: async () => {
      toast.success("مشتری به‌روز شد");
      setEditCustomer(null);
      await invalidateCustomers();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const createInvoiceM = useMutation({
    mutationFn: (d: z.infer<typeof invoiceSchema>) =>
      accountingApi.customers.createInvoice(tenantId!, {
        customer_id: detailCustomer!.id,
        invoice_number: d.invoice_number?.trim() || undefined,
        invoice_date: d.invoice_date,
        due_date: d.due_date || undefined,
        total_amount: d.total_amount,
      }),
    onSuccess: async () => {
      toast.success("فاکتور ثبت شد");
      setInvoiceOpen(false);
      invoiceForm.reset();
      await invalidateInvoices();
      await invalidateCustomers();
      if (detailCustomer) {
        await qc.invalidateQueries({
          queryKey: ["accounting", tenantId, "customer-aging", detailCustomer.id],
        });
      }
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const openEdit = (row: CustomerRow) => {
    setEditCustomer(row);
    editForm.reset({
      name: row.name,
      credit_limit: "",
      is_active: row.is_active,
    });
  };

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

  const aging = agingQ.data;

  return (
    <div>
      <PageHeader
        title="مشتریان"
        description="حساب‌های دریافتنی — مدیریت مشتری، سررسید و فاکتور."
        actions={
          <Button onClick={() => setCreateOpen(true)}>
            <Plus className="h-4 w-4" />
            مشتری جدید
          </Button>
        }
      />

      <DataTable
        columns={[
          { key: "code", header: "کد" },
          { key: "name", header: "نام" },
          {
            key: "outstanding_balance",
            header: "مانده",
            render: (r) => formatMoney(String(r.outstanding_balance)),
          },
          {
            key: "is_active",
            header: "وضعیت",
            render: (r) => (
              <Badge tone={r.is_active ? "success" : "default"}>
                {r.is_active ? "فعال" : "غیرفعال"}
              </Badge>
            ),
          },
          {
            key: "actions",
            header: "عملیات",
            render: (r) => (
              <div className="flex flex-wrap gap-1">
                <Button
                  type="button"
                  size="sm"
                  variant="outline"
                  onClick={() => setDetailCustomer(r as unknown as CustomerRow)}
                >
                  <Eye className="h-3.5 w-3.5" />
                  جزئیات
                </Button>
                <Button
                  type="button"
                  size="sm"
                  variant="secondary"
                  onClick={() => openEdit(r as unknown as CustomerRow)}
                >
                  <Pencil className="h-3.5 w-3.5" />
                  ویرایش
                </Button>
              </div>
            ),
          },
        ]}
        rows={(listQ.data ?? []) as unknown as Record<string, unknown>[]}
        empty={<EmptyState action={<Button onClick={() => setCreateOpen(true)}>ایجاد مشتری</Button>} />}
      />

      <Dialog open={createOpen} onClose={() => setCreateOpen(false)} title="مشتری جدید">
        <form className="space-y-3" onSubmit={createForm.handleSubmit((d) => createM.mutate(d))}>
          <FormField label="کد (اختیاری — خودکار)" error={createForm.formState.errors.code?.message}>
            <Input {...createForm.register("code")} placeholder="خودکار" />
          </FormField>
          <FormField label="نام" error={createForm.formState.errors.name?.message}>
            <Input {...createForm.register("name")} />
          </FormField>
          <FormField label="سقف اعتبار">
            <MoneyInput {...createForm.register("credit_limit")} />
          </FormField>
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setCreateOpen(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={createM.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Dialog>

      <Drawer
        open={!!editCustomer}
        onClose={() => setEditCustomer(null)}
        title="ویرایش مشتری"
        description={editCustomer ? `${editCustomer.code} — ${editCustomer.name}` : undefined}
      >
        <form className="space-y-4" onSubmit={editForm.handleSubmit((d) => updateM.mutate(d))}>
          <FormField label="نام" error={editForm.formState.errors.name?.message}>
            <Input {...editForm.register("name")} />
          </FormField>
          <FormField label="سقف اعتبار">
            <MoneyInput {...editForm.register("credit_limit")} />
          </FormField>
          <Checkbox label="فعال" {...editForm.register("is_active")} />
          <div className="flex justify-end gap-2 pt-2">
            <Button type="button" variant="outline" onClick={() => setEditCustomer(null)}>
              انصراف
            </Button>
            <Button type="submit" disabled={updateM.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Drawer>

      <Drawer
        open={!!detailCustomer}
        onClose={() => {
          setDetailCustomer(null);
          setInvoiceOpen(false);
        }}
        title={detailCustomer?.name ?? "جزئیات مشتری"}
        description={detailCustomer ? `کد: ${detailCustomer.code}` : undefined}
        width="lg"
      >
        {detailCustomer && (
          <div className="space-y-6">
            <div className="grid gap-3 sm:grid-cols-2">
              <StatCard label="مانده کل" value={formatMoney(detailCustomer.outstanding_balance)} />
              {agingQ.isLoading ? (
                <p className="text-sm text-[var(--muted)]">در حال بارگذاری سررسید…</p>
              ) : agingQ.error ? (
                <p className="text-sm text-red-600">{agingQ.error.message}</p>
              ) : aging ? (
                <>
                  <StatCard label="جاری" value={formatMoney(aging.current)} />
                  <StatCard label="۱–۳۰ روز" value={formatMoney(aging.days_1_30)} />
                  <StatCard label="۳۱–۶۰ روز" value={formatMoney(aging.days_31_60)} />
                  <StatCard label="۶۱–۹۰ روز" value={formatMoney(aging.days_61_90)} />
                  <StatCard label="۹۰+ روز" value={formatMoney(aging.days_90_plus)} />
                  <StatCard label="مجموع سررسید" value={formatMoney(aging.total)} />
                </>
              ) : null}
            </div>

            <div>
              <div className="mb-3 flex flex-wrap items-center justify-between gap-2">
                <h3 className="text-sm font-semibold text-secondary">فاکتورهای دریافتنی</h3>
                <Button type="button" size="sm" onClick={() => setInvoiceOpen(true)}>
                  <Plus className="h-3.5 w-3.5" />
                  فاکتور جدید
                </Button>
              </div>
              {invoicesQ.isLoading ? (
                <LoadingState label="بارگذاری فاکتورها…" />
              ) : invoicesQ.error ? (
                <ErrorState message={invoicesQ.error.message} onRetry={() => invoicesQ.refetch()} />
              ) : (
                <DataTable
                  columns={[
                    { key: "invoice_number", header: "شماره" },
                    {
                      key: "invoice_date",
                      header: "تاریخ",
                      render: (r) => <JalaliDateText value={String(r.invoice_date ?? "")} />,
                    },
                    {
                      key: "total_amount",
                      header: "مبلغ",
                      render: (r) => formatMoney(String(r.total_amount)),
                    },
                    {
                      key: "remaining_amount",
                      header: "مانده",
                      render: (r) => formatMoney(String(r.remaining_amount)),
                    },
                    {
                      key: "status",
                      header: "وضعیت",
                      render: (r) => <Badge>{String(r.status)}</Badge>,
                    },
                  ]}
                  rows={(invoicesQ.data ?? []) as unknown as Record<string, unknown>[]}
                  empty={<EmptyState title="فاکتوری ثبت نشده" />}
                />
              )}
            </div>
          </div>
        )}
      </Drawer>

      <Dialog open={invoiceOpen} onClose={() => setInvoiceOpen(false)} title="فاکتور دریافتنی جدید">
        <form className="space-y-3" onSubmit={invoiceForm.handleSubmit((d) => createInvoiceM.mutate(d))}>
          <FormField label="شماره فاکتور (اختیاری — خودکار)" error={invoiceForm.formState.errors.invoice_number?.message}>
            <Input {...invoiceForm.register("invoice_number")} placeholder="خودکار" />
          </FormField>
          <FormField label="تاریخ فاکتور" error={invoiceForm.formState.errors.invoice_date?.message}>
            <Controller
              control={invoiceForm.control}
              name="invoice_date"
              render={({ field }) => (
                <DatePicker
                  value={field.value}
                  onChange={field.onChange}
                  onBlur={field.onBlur}
                  name={field.name}
                />
              )}
            />
          </FormField>
          <FormField label="سررسید">
            <Controller
              control={invoiceForm.control}
              name="due_date"
              render={({ field }) => (
                <DatePicker
                  value={field.value}
                  onChange={field.onChange}
                  onBlur={field.onBlur}
                  name={field.name}
                />
              )}
            />
          </FormField>
          <FormField label="مبلغ کل" error={invoiceForm.formState.errors.total_amount?.message}>
            <MoneyInput {...invoiceForm.register("total_amount")} />
          </FormField>
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setInvoiceOpen(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={createInvoiceM.isPending}>
              ثبت فاکتور
            </Button>
          </div>
        </form>
      </Dialog>
    </div>
  );
}
