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

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

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

export function CostCentersPage() {
  const { tenantId } = useTenantId();
  const qc = useQueryClient();
  const [createOpen, setCreateOpen] = useState(false);
  const [selected, setSelected] = useState<CostCenter | null>(null);
  const [archiveId, setArchiveId] = useState<string | null>(null);

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

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

  const activeCenters = useMemo(
    () => (listQ.data ?? []).filter((c) => c.is_active),
    [listQ.data]
  );

  const parentName = (id: string | null | undefined) => {
    if (!id) return "—";
    return listQ.data?.find((c) => c.id === id)?.name ?? id;
  };

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

  const createM = useMutation({
    mutationFn: (d: z.infer<typeof createSchema>) =>
      accountingApi.costCenters.create(tenantId!, {
        code: d.code,
        name: d.name,
        parent_id: d.parent_id || null,
      }),
    onSuccess: async () => {
      toast.success("مرکز هزینه ایجاد شد");
      setCreateOpen(false);
      createForm.reset();
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const updateM = useMutation({
    mutationFn: (d: z.infer<typeof editSchema>) =>
      accountingApi.costCenters.update(tenantId!, selected!.id, {
        name: d.name,
        parent_id: d.parent_id || null,
      }),
    onSuccess: async () => {
      toast.success("مرکز هزینه به‌روز شد");
      setSelected(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const archiveM = useMutation({
    mutationFn: (id: string) => accountingApi.costCenters.archive(tenantId!, id),
    onSuccess: async () => {
      toast.success("مرکز هزینه آرشیو شد");
      setArchiveId(null);
      setSelected(null);
      await invalidate();
    },
    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()} />;

  const parentOptions = (excludeId?: string) =>
    activeCenters.filter((c) => c.id !== excludeId);

  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: "parent_id",
            header: "والد",
            render: (r) => parentName(r.parent_id as string | null | undefined),
          },
          {
            key: "is_active",
            header: "وضعیت",
            render: (r) => (
              <Badge tone={r.is_active ? "success" : "default"}>
                {r.is_active ? "فعال" : "آرشیو"}
              </Badge>
            ),
          },
          {
            key: "actions",
            header: "عملیات",
            render: (r) => {
              const id = String(r.id);
              const active = Boolean(r.is_active);
              return active ? (
                <div className="flex flex-wrap gap-1">
                  <Button
                    type="button"
                    size="sm"
                    variant="outline"
                    onClick={() => {
                      const c = listQ.data?.find((x) => x.id === id);
                      if (c) {
                        setSelected(c);
                        editForm.reset({ name: c.name, parent_id: c.parent_id ?? "" });
                      }
                    }}
                  >
                    <Pencil className="h-3.5 w-3.5" />
                  </Button>
                  <Button type="button" size="sm" variant="ghost" onClick={() => setArchiveId(id)}>
                    <Archive className="h-3.5 w-3.5" />
                  </Button>
                </div>
              ) : (
                "—"
              );
            },
          },
        ]}
        rows={(listQ.data ?? []) as unknown as Record<string, unknown>[]}
        empty={
          <EmptyState title="مرکز هزینه‌ای ثبت نشده" 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))}>
          <div>
            <Label>کد</Label>
            <Input {...createForm.register("code")} />
            <FieldError>{createForm.formState.errors.code?.message}</FieldError>
          </div>
          <div>
            <Label>نام</Label>
            <Input {...createForm.register("name")} />
            <FieldError>{createForm.formState.errors.name?.message}</FieldError>
          </div>
          <div>
            <Label>مرکز والد (اختیاری)</Label>
            <Select {...createForm.register("parent_id")}>
              <option value="">بدون والد</option>
              {parentOptions().map((c) => (
                <option key={c.id} value={c.id}>
                  {c.code} — {c.name}
                </option>
              ))}
            </Select>
          </div>
          <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={!!selected}
        onClose={() => setSelected(null)}
        title="ویرایش مرکز هزینه"
        description={selected ? `${selected.code}` : undefined}
      >
        <form className="space-y-4" onSubmit={editForm.handleSubmit((d) => updateM.mutate(d))}>
          <div>
            <Label>نام</Label>
            <Input {...editForm.register("name")} />
            <FieldError>{editForm.formState.errors.name?.message}</FieldError>
          </div>
          <div>
            <Label>مرکز والد (اختیاری)</Label>
            <Select {...editForm.register("parent_id")}>
              <option value="">بدون والد</option>
              {parentOptions(selected?.id).map((c) => (
                <option key={c.id} value={c.id}>
                  {c.code} — {c.name}
                </option>
              ))}
            </Select>
          </div>
          <div className="flex justify-end gap-2 pt-2">
            <Button type="button" variant="outline" onClick={() => setSelected(null)}>
              انصراف
            </Button>
            <Button type="submit" disabled={updateM.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Drawer>

      <ConfirmDialog
        open={!!archiveId}
        onClose={() => setArchiveId(null)}
        onConfirm={() => archiveId && archiveM.mutate(archiveId)}
        title="آرشیو مرکز هزینه؟"
        description="مرکز آرشیو شده در اسناد جدید قابل انتخاب نیست."
        confirmLabel="آرشیو"
        danger
        loading={archiveM.isPending}
      />
    </div>
  );
}
