"use client";

import { useMemo, useState } from "react";
import { 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 { Plus, Archive, Pencil } from "lucide-react";
import { accountingApi, type Account, type ChartOfAccounts } from "@/src/modules/accounting/services/accounting-api";
import { useTenantId } from "@/hooks/useTenantId";
import {
  PageHeader,
  Button,
  Dialog,
  Input,
  Label,
  FieldError,
  Textarea,
  DataTable,
  EmptyState,
  LoadingState,
  ErrorState,
  Badge,
  Select,
  Drawer,
  TableToolbar,
  Tabs,
  Checkbox,
} from "@/src/shared/ui";

const chartSchema = z.object({
  code: z.string().min(1, "کد الزامی است"),
  name: z.string().min(1, "نام الزامی است"),
  description: z.string().optional(),
  is_default: z.boolean().optional(),
});

const accountSchema = z.object({
  chart_id: z.string().uuid("دفتر حساب را انتخاب کنید"),
  code: z.string().min(1, "کد الزامی است"),
  name: z.string().min(1, "نام الزامی است"),
  account_type: z.string().min(1),
  account_category: z.string().min(1),
  parent_id: z.string().optional(),
  is_group: z.boolean().optional(),
  is_postable: z.boolean().optional(),
  description: z.string().optional(),
});

type ChartForm = z.infer<typeof chartSchema>;
const editChartSchema = chartSchema.omit({ code: true }).extend({ code: z.string().optional() });
type EditChartForm = z.infer<typeof editChartSchema>;
type AccountForm = z.infer<typeof accountSchema>;

const ACCOUNT_TYPES = [
  { value: "asset", label: "دارایی" },
  { value: "liability", label: "بدهی" },
  { value: "equity", label: "حقوق صاحبان سهام" },
  { value: "revenue", label: "درآمد" },
  { value: "expense", label: "هزینه" },
];

const ACCOUNT_CATEGORIES = [
  { value: "current_asset", label: "دارایی جاری" },
  { value: "non_current_asset", label: "دارایی غیرجاری" },
  { value: "current_liability", label: "بدهی جاری" },
  { value: "non_current_liability", label: "بدهی غیرجاری" },
  { value: "equity", label: "حقوق صاحبان سهام" },
  { value: "operating_revenue", label: "درآمد عملیاتی" },
  { value: "other_revenue", label: "سایر درآمدها" },
  { value: "operating_expense", label: "هزینه عملیاتی" },
  { value: "other_expense", label: "سایر هزینه‌ها" },
];

export function ChartOfAccountsPage() {
  const { tenantId } = useTenantId();
  const qc = useQueryClient();
  const [tab, setTab] = useState("accounts");
  const [chartOpen, setChartOpen] = useState(false);
  const [accountOpen, setAccountOpen] = useState(false);
  const [editChart, setEditChart] = useState<ChartOfAccounts | null>(null);
  const [selected, setSelected] = useState<Account | null>(null);
  const [filterChart, setFilterChart] = useState<string>("");
  const [search, setSearch] = useState("");
  const [showInactive, setShowInactive] = useState(false);

  const chartsQ = useQuery({
    queryKey: ["accounting", tenantId, "charts"],
    queryFn: () => accountingApi.charts.list(tenantId!),
    enabled: !!tenantId,
  });
  const accountsQ = useQuery({
    queryKey: ["accounting", tenantId, "accounts", filterChart],
    queryFn: () => accountingApi.accounts.list(tenantId!, 1, 500, filterChart || undefined),
    enabled: !!tenantId,
  });

  const chartForm = useForm<ChartForm>({
    resolver: zodResolver(chartSchema),
    defaultValues: { code: "", name: "", description: "", is_default: false },
  });
  const accountForm = useForm<AccountForm>({
    resolver: zodResolver(accountSchema),
    defaultValues: {
      chart_id: "",
      code: "",
      name: "",
      account_type: "asset",
      account_category: "current_asset",
      parent_id: "",
      is_group: false,
      is_postable: true,
      description: "",
    },
  });
  const editChartForm = useForm<EditChartForm>({
    resolver: zodResolver(editChartSchema),
  });
  const editAccountForm = useForm({
    defaultValues: { name: "", status: "active", description: "", is_postable: true },
  });

  const invalidate = async () => {
    await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "charts"] });
    await qc.invalidateQueries({ queryKey: ["accounting", tenantId, "accounts"] });
  };

  const createChart = useMutation({
    mutationFn: (data: ChartForm) => accountingApi.charts.create(tenantId!, data),
    onSuccess: async () => {
      toast.success("دفتر حساب ایجاد شد");
      setChartOpen(false);
      chartForm.reset();
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const updateChart = useMutation({
    mutationFn: (data: ChartForm) =>
      accountingApi.charts.update(tenantId!, editChart!.id, {
        name: data.name,
        description: data.description,
        is_default: data.is_default,
      }),
    onSuccess: async () => {
      toast.success("دفتر به‌روز شد");
      setEditChart(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const archiveChart = useMutation({
    mutationFn: (id: string) => accountingApi.charts.archive(tenantId!, id),
    onSuccess: async () => {
      toast.success("دفتر آرشیو شد");
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const createAccount = useMutation({
    mutationFn: (data: AccountForm) =>
      accountingApi.accounts.create(tenantId!, {
        ...data,
        parent_id: data.parent_id || null,
        is_postable: data.is_postable ?? true,
        is_group: data.is_group ?? false,
      }),
    onSuccess: async () => {
      toast.success("حساب ایجاد شد");
      setAccountOpen(false);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const updateAccount = useMutation({
    mutationFn: (body: { name: string; status: string; description?: string; is_postable: boolean }) =>
      accountingApi.accounts.update(tenantId!, selected!.id, body),
    onSuccess: async () => {
      toast.success("حساب به‌روز شد");
      setSelected(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const archiveAccount = useMutation({
    mutationFn: (id: string) => accountingApi.accounts.archive(tenantId!, id),
    onSuccess: async () => {
      toast.success("حساب آرشیو شد");
      setSelected(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const rows = useMemo(() => {
    let list = accountsQ.data ?? [];
    if (!showInactive) list = list.filter((a) => a.status === "active");
    if (search.trim()) {
      const q = search.trim().toLowerCase();
      list = list.filter(
        (a) => a.code.toLowerCase().includes(q) || a.name.toLowerCase().includes(q)
      );
    }
    return [...list].sort((a, b) => a.code.localeCompare(b.code, "fa"));
  }, [accountsQ.data, search, showInactive]);

  if (!tenantId) return <LoadingState />;
  if (chartsQ.isLoading || accountsQ.isLoading) return <LoadingState />;
  if (chartsQ.error || accountsQ.error) {
    return (
      <ErrorState
        message={(chartsQ.error || accountsQ.error)?.message || "خطا"}
        onRetry={() => {
          void chartsQ.refetch();
          void accountsQ.refetch();
        }}
      />
    );
  }

  const chartName = (id: string) => chartsQ.data?.find((c) => c.id === id)?.name ?? id;

  return (
    <div>
      <PageHeader
        title="دفتر حساب‌ها"
        description="درخت حساب‌ها، ویرایش، آرشیو و جزئیات — API واقعی."
        actions={
          <>
            <Button type="button" variant="outline" onClick={() => setChartOpen(true)}>
              <Plus className="h-4 w-4" />
              دفتر جدید
            </Button>
            <Button
              type="button"
              onClick={() => {
                if (chartsQ.data?.[0]) accountForm.setValue("chart_id", filterChart || chartsQ.data[0].id);
                setAccountOpen(true);
              }}
              disabled={!chartsQ.data?.length}
            >
              <Plus className="h-4 w-4" />
              حساب جدید
            </Button>
          </>
        }
      />

      <Tabs
        className="mb-4"
        value={tab}
        onChange={setTab}
        items={[
          { id: "accounts", label: "حساب‌ها" },
          { id: "charts", label: "دفاتر" },
        ]}
      />

      {tab === "charts" ? (
        <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
          {chartsQ.data?.map((c) => (
            <div key={c.id} className="rounded-2xl border border-[var(--border)] bg-[var(--surface)] p-4">
              <div className="flex items-start justify-between gap-2">
                <div>
                  <p className="font-semibold text-secondary">{c.name}</p>
                  <p className="mt-1 text-sm text-[var(--muted)]" dir="ltr">
                    {c.code}
                  </p>
                </div>
                <div className="flex flex-col items-end gap-1">
                  {c.is_default ? <Badge tone="primary">پیش‌فرض</Badge> : null}
                  <Badge tone={c.is_active ? "success" : "default"}>
                    {c.is_active ? "فعال" : "آرشیو"}
                  </Badge>
                </div>
              </div>
              <div className="mt-3 flex flex-wrap gap-2">
                <Button
                  type="button"
                  size="sm"
                  variant="outline"
                  onClick={() => {
                    setEditChart(c);
                    editChartForm.reset({
                      code: c.code,
                      name: c.name,
                      description: c.description ?? "",
                      is_default: c.is_default,
                    });
                  }}
                >
                  <Pencil className="h-3.5 w-3.5" />
                  ویرایش
                </Button>
                {c.is_active ? (
                  <Button
                    type="button"
                    size="sm"
                    variant="ghost"
                    onClick={() => archiveChart.mutate(c.id)}
                  >
                    <Archive className="h-3.5 w-3.5" />
                    آرشیو
                  </Button>
                ) : null}
                <Button type="button" size="sm" variant="ghost" onClick={() => { setFilterChart(c.id); setTab("accounts"); }}>
                  مشاهده حساب‌ها
                </Button>
              </div>
            </div>
          ))}
          {!chartsQ.data?.length ? (
            <EmptyState
              title="دفتری ثبت نشده"
              description="ابتدا یک دفتر حساب بسازید یا از راه‌اندازی قالب وارد کنید."
              action={
                <Button type="button" onClick={() => setChartOpen(true)}>
                  ایجاد دفتر
                </Button>
              }
            />
          ) : null}
        </div>
      ) : (
        <>
          <TableToolbar
            search={search}
            onSearchChange={setSearch}
            searchPlaceholder="جستجوی کد یا نام…"
            actions={
              <>
                <Select
                  value={filterChart}
                  onChange={(e) => setFilterChart(e.target.value)}
                  className="w-44"
                >
                  <option value="">همه دفاتر</option>
                  {chartsQ.data?.map((c) => (
                    <option key={c.id} value={c.id}>
                      {c.name}
                    </option>
                  ))}
                </Select>
                <Checkbox
                  label="نمایش غیرفعال"
                  checked={showInactive}
                  onChange={(e) => setShowInactive(e.target.checked)}
                />
              </>
            }
          />

          {/* Mobile cards */}
          <div className="mb-4 space-y-2 md:hidden">
            {rows.map((r) => (
              <button
                key={r.id}
                type="button"
                className="w-full rounded-2xl border border-[var(--border)] bg-[var(--surface)] p-3 text-right"
                onClick={() => {
                  setSelected(r);
                  editAccountForm.reset({
                    name: r.name,
                    status: r.status,
                    description: r.description ?? "",
                    is_postable: r.is_postable,
                  });
                }}
              >
                <div className="flex items-center justify-between gap-2">
                  <span className="font-medium text-secondary">{r.name}</span>
                  <Badge tone={r.status === "active" ? "success" : "default"}>{r.status}</Badge>
                </div>
                <p className="mt-1 text-xs text-[var(--muted)]" dir="ltr">
                  {r.code} · {chartName(r.chart_id)}
                </p>
              </button>
            ))}
            {!rows.length ? <EmptyState title="حسابی نیست" description="حساب جدید اضافه کنید." /> : null}
          </div>

          <div className="hidden md:block">
            <DataTable
              columns={[
                {
                  key: "code",
                  header: "کد",
                  render: (r) => (
                    <span style={{ paddingInlineStart: `${(Number(r.level) - 1) * 12}px` }} dir="ltr">
                      {String(r.code)}
                    </span>
                  ),
                },
                { key: "name", header: "نام" },
                {
                  key: "chart_id",
                  header: "دفتر",
                  render: (r) => chartName(String(r.chart_id)),
                },
                {
                  key: "account_type",
                  header: "نوع",
                  render: (r) =>
                    ACCOUNT_TYPES.find((t) => t.value === r.account_type)?.label ?? String(r.account_type),
                },
                {
                  key: "status",
                  header: "وضعیت",
                  render: (r) => (
                    <Badge tone={r.status === "active" ? "success" : "default"}>{String(r.status)}</Badge>
                  ),
                },
                {
                  key: "id",
                  header: "",
                  render: (r) => (
                    <Button
                      type="button"
                      size="sm"
                      variant="ghost"
                      onClick={() => {
                        const acc = r as unknown as Account;
                        setSelected(acc);
                        editAccountForm.reset({
                          name: acc.name,
                          status: acc.status,
                          description: acc.description ?? "",
                          is_postable: acc.is_postable,
                        });
                      }}
                    >
                      جزئیات
                    </Button>
                  ),
                },
              ]}
              rows={rows as unknown as Record<string, unknown>[]}
              empty={
                <EmptyState
                  title="حسابی ثبت نشده"
                  description="ابتدا دفتر بسازید یا از قالب وارد کنید."
                  action={
                    <Button type="button" onClick={() => setChartOpen(true)}>
                      ایجاد دفتر حساب
                    </Button>
                  }
                />
              }
            />
          </div>
        </>
      )}

      <Dialog open={chartOpen} onClose={() => setChartOpen(false)} title="ایجاد دفتر حساب">
        <form className="space-y-3" onSubmit={chartForm.handleSubmit((d) => createChart.mutate(d))}>
          <div>
            <Label htmlFor="chart-code">کد</Label>
            <Input id="chart-code" {...chartForm.register("code")} />
            <FieldError>{chartForm.formState.errors.code?.message}</FieldError>
          </div>
          <div>
            <Label htmlFor="chart-name">نام</Label>
            <Input id="chart-name" {...chartForm.register("name")} />
            <FieldError>{chartForm.formState.errors.name?.message}</FieldError>
          </div>
          <div>
            <Label htmlFor="chart-desc">توضیح</Label>
            <Textarea id="chart-desc" {...chartForm.register("description")} />
          </div>
          <Checkbox label="دفتر پیش‌فرض" {...chartForm.register("is_default")} />
          <div className="flex justify-end gap-2 pt-2">
            <Button type="button" variant="outline" onClick={() => setChartOpen(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={createChart.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Dialog>

      <Dialog open={!!editChart} onClose={() => setEditChart(null)} title="ویرایش دفتر حساب">
        <form className="space-y-3" onSubmit={editChartForm.handleSubmit((d) => updateChart.mutate(d as ChartForm))}>
          <div>
            <Label>کد</Label>
            <Input disabled value={editChart?.code ?? ""} />
          </div>
          <div>
            <Label htmlFor="edit-chart-name">نام</Label>
            <Input id="edit-chart-name" {...editChartForm.register("name")} />
          </div>
          <div>
            <Label>توضیح</Label>
            <Textarea {...editChartForm.register("description")} />
          </div>
          <Checkbox label="دفتر پیش‌فرض" {...editChartForm.register("is_default")} />
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setEditChart(null)}>
              انصراف
            </Button>
            <Button type="submit" disabled={updateChart.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Dialog>

      <Dialog open={accountOpen} onClose={() => setAccountOpen(false)} title="ایجاد حساب" size="lg">
        <form
          className="grid gap-3 sm:grid-cols-2"
          onSubmit={accountForm.handleSubmit((d) => createAccount.mutate(d))}
        >
          <div className="sm:col-span-2">
            <Label>دفتر حساب</Label>
            <Select {...accountForm.register("chart_id")}>
              <option value="">انتخاب کنید</option>
              {chartsQ.data?.filter((c) => c.is_active).map((c) => (
                <option key={c.id} value={c.id}>
                  {c.code} — {c.name}
                </option>
              ))}
            </Select>
            <FieldError>{accountForm.formState.errors.chart_id?.message}</FieldError>
          </div>
          <div>
            <Label>کد</Label>
            <Input {...accountForm.register("code")} />
            <FieldError>{accountForm.formState.errors.code?.message}</FieldError>
          </div>
          <div>
            <Label>نام</Label>
            <Input {...accountForm.register("name")} />
            <FieldError>{accountForm.formState.errors.name?.message}</FieldError>
          </div>
          <div>
            <Label>نوع</Label>
            <Select {...accountForm.register("account_type")}>
              {ACCOUNT_TYPES.map((t) => (
                <option key={t.value} value={t.value}>
                  {t.label}
                </option>
              ))}
            </Select>
          </div>
          <div>
            <Label>دسته</Label>
            <Select {...accountForm.register("account_category")}>
              {ACCOUNT_CATEGORIES.map((t) => (
                <option key={t.value} value={t.value}>
                  {t.label}
                </option>
              ))}
            </Select>
          </div>
          <div className="sm:col-span-2">
            <Label>حساب والد</Label>
            <Select {...accountForm.register("parent_id")}>
              <option value="">بدون والد</option>
              {(accountsQ.data ?? [])
                .filter((a) => a.status === "active")
                .map((a) => (
                  <option key={a.id} value={a.id}>
                    {a.code} — {a.name}
                  </option>
                ))}
            </Select>
          </div>
          <Checkbox label="گروه حساب" {...accountForm.register("is_group")} />
          <Checkbox label="قابل ثبت سند" {...accountForm.register("is_postable")} />
          <div className="flex justify-end gap-2 sm:col-span-2">
            <Button type="button" variant="outline" onClick={() => setAccountOpen(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={createAccount.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Dialog>

      <Drawer
        open={!!selected}
        onClose={() => setSelected(null)}
        title={selected ? `${selected.code} — ${selected.name}` : "حساب"}
        description={selected ? chartName(selected.chart_id) : undefined}
      >
        {selected ? (
          <form
            className="space-y-3"
            onSubmit={editAccountForm.handleSubmit((d) =>
              updateAccount.mutate({
                name: d.name,
                status: d.status,
                description: d.description,
                is_postable: d.is_postable,
              })
            )}
          >
            <div>
              <Label>نام</Label>
              <Input {...editAccountForm.register("name")} />
            </div>
            <div>
              <Label>وضعیت</Label>
              <Select {...editAccountForm.register("status")}>
                <option value="active">active</option>
                <option value="inactive">inactive</option>
                <option value="closed">closed</option>
              </Select>
            </div>
            <div>
              <Label>توضیح</Label>
              <Textarea {...editAccountForm.register("description")} />
            </div>
            <Checkbox label="قابل ثبت سند" {...editAccountForm.register("is_postable")} />
            <p className="text-xs text-[var(--muted)]">
              نوع: {selected.account_type} · دسته: {selected.account_category} · سطح: {selected.level}
            </p>
            <div className="flex flex-wrap gap-2 pt-2">
              <Button type="submit" disabled={updateAccount.isPending}>
                ذخیره تغییرات
              </Button>
              {selected.status === "active" ? (
                <Button
                  type="button"
                  variant="outline"
                  onClick={() => archiveAccount.mutate(selected.id)}
                >
                  آرشیو
                </Button>
              ) : null}
            </div>
          </form>
        ) : null}
      </Drawer>
    </div>
  );
}
