"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 { Plus, Pencil, Archive } from "lucide-react";
import { accountingApi, type Project } 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,
  DatePicker,
  JalaliDateText,
} from "@/src/shared/ui";

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

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

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

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

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

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

  const createM = useMutation({
    mutationFn: (d: z.infer<typeof createSchema>) =>
      accountingApi.projects.create(tenantId!, {
        code: d.code,
        name: d.name,
        start_date: d.start_date || undefined,
        end_date: d.end_date || undefined,
      }),
    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.projects.update(tenantId!, selected!.id, {
        name: d.name,
        start_date: d.start_date || null,
        end_date: d.end_date || null,
      }),
    onSuccess: async () => {
      toast.success("پروژه به‌روز شد");
      setSelected(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const archiveM = useMutation({
    mutationFn: (id: string) => accountingApi.projects.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()} />;

  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: "start_date",
            header: "شروع",
            render: (r) =>
              r.start_date ? <JalaliDateText value={String(r.start_date)} /> : "—",
          },
          {
            key: "end_date",
            header: "پایان",
            render: (r) => (r.end_date ? <JalaliDateText value={String(r.end_date)} /> : "—"),
          },
          {
            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 p = listQ.data?.find((x) => x.id === id);
                      if (p) {
                        setSelected(p);
                        editForm.reset({
                          name: p.name,
                          start_date: p.start_date ?? "",
                          end_date: p.end_date ?? "",
                        });
                      }
                    }}
                  >
                    <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 className="grid grid-cols-2 gap-3">
            <div>
              <Label>تاریخ شروع</Label>
              <Controller
                control={createForm.control}
                name="start_date"
                render={({ field }) => (
                  <DatePicker value={field.value ?? ""} onChange={field.onChange} onBlur={field.onBlur} name={field.name} />
                )}
              />
            </div>
            <div>
              <Label>تاریخ پایان</Label>
              <Controller
                control={createForm.control}
                name="end_date"
                render={({ field }) => (
                  <DatePicker value={field.value ?? ""} onChange={field.onChange} onBlur={field.onBlur} name={field.name} />
                )}
              />
            </div>
          </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 className="grid grid-cols-2 gap-3">
            <div>
              <Label>تاریخ شروع</Label>
              <Controller
                control={editForm.control}
                name="start_date"
                render={({ field }) => (
                  <DatePicker value={field.value ?? ""} onChange={field.onChange} onBlur={field.onBlur} name={field.name} />
                )}
              />
            </div>
            <div>
              <Label>تاریخ پایان</Label>
              <Controller
                control={editForm.control}
                name="end_date"
                render={({ field }) => (
                  <DatePicker value={field.value ?? ""} onChange={field.onChange} onBlur={field.onBlur} name={field.name} />
                )}
              />
            </div>
          </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>
  );
}
