"use client";

import { useEffect, useState } from "react";
import { useParams, useRouter } from "next/navigation";
import { Controller, useFieldArray, 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, Trash2 } from "lucide-react";
import { accountingApi } from "@/lib/accounting-api";
import { useTenantId } from "@/hooks/useTenantId";
import { formatMoney } from "@/lib/utils";
import {
  PageHeader,
  Button,
  Badge,
  DataTable,
  LoadingState,
  ErrorState,
  ConfirmDialog,
  Card,
  CardContent,
  JalaliDateText,
  DatePicker,
  Input,
  Label,
  FieldError,
  Select,
  MoneyInput,
} from "@/components/ds";

const lineSchema = z.object({
  account_id: z.string().uuid("حساب معتبر انتخاب کنید"),
  debit: z.string().min(1),
  credit: z.string().min(1),
  description: z.string().optional(),
  cost_center_id: z.string().optional(),
  project_id: z.string().optional(),
});

const editSchema = z.object({
  voucher_date: z.string().min(1),
  description: z.string().optional(),
  lines: z.array(lineSchema).min(2, "حداقل دو ردیف لازم است"),
});

type EditForm = z.infer<typeof editSchema>;

export default function VoucherDetailPage() {
  const params = useParams<{ id: string }>();
  const id = params.id;
  const { tenantId } = useTenantId();
  const qc = useQueryClient();
  const router = useRouter();
  const [confirm, setConfirm] = useState<"post" | "reverse" | "cancel" | null>(null);
  const [editing, setEditing] = useState(false);

  const voucherQ = useQuery({
    queryKey: ["accounting", tenantId, "voucher", id],
    queryFn: () => accountingApi.vouchers.get(tenantId!, id),
    enabled: !!tenantId && !!id,
  });
  const accountsQ = useQuery({
    queryKey: ["accounting", tenantId, "accounts"],
    queryFn: () => accountingApi.accounts.list(tenantId!),
    enabled: !!tenantId,
  });
  const costCentersQ = useQuery({
    queryKey: ["accounting", tenantId, "cost-centers"],
    queryFn: () => accountingApi.costCenters.list(tenantId!),
    enabled: !!tenantId,
  });
  const projectsQ = useQuery({
    queryKey: ["accounting", tenantId, "projects"],
    queryFn: () => accountingApi.projects.list(tenantId!),
    enabled: !!tenantId,
  });

  const editForm = useForm<EditForm>({
    resolver: zodResolver(editSchema),
    defaultValues: { voucher_date: "", description: "", lines: [] },
  });
  const { fields, append, remove } = useFieldArray({ control: editForm.control, name: "lines" });

  useEffect(() => {
    const v = voucherQ.data;
    if (!v || v.status !== "draft") return;
    editForm.reset({
      voucher_date: v.voucher_date,
      description: v.description ?? "",
      lines: v.lines.map((l) => ({
        account_id: l.account_id,
        debit: l.debit,
        credit: l.credit,
        description: l.description ?? "",
        cost_center_id: l.cost_center_id ?? "",
        project_id: l.project_id ?? "",
      })),
    });
  }, [voucherQ.data, editForm]);

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

  const updateM = useMutation({
    mutationFn: (data: EditForm) =>
      accountingApi.vouchers.update(tenantId!, id, {
        voucher_date: data.voucher_date,
        description: data.description || undefined,
        lines: data.lines.map((l) => ({
          account_id: l.account_id,
          debit: l.debit || "0",
          credit: l.credit || "0",
          description: l.description || undefined,
          cost_center_id: l.cost_center_id || null,
          project_id: l.project_id || null,
        })),
      }),
    onSuccess: async () => {
      toast.success("سند به‌روز شد");
      setEditing(false);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const validateM = useMutation({
    mutationFn: () => accountingApi.vouchers.validate(tenantId!, id),
    onSuccess: async () => {
      toast.success("سند اعتبارسنجی شد");
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });
  const postM = useMutation({
    mutationFn: () => accountingApi.vouchers.post(tenantId!, id, "manual"),
    onSuccess: async () => {
      toast.success("سند ثبت قطعی شد");
      setConfirm(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });
  const reverseM = useMutation({
    mutationFn: () => accountingApi.vouchers.reverse(tenantId!, id),
    onSuccess: async () => {
      toast.success("سند برگشت خورد");
      setConfirm(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });
  const cancelM = useMutation({
    mutationFn: () => accountingApi.vouchers.cancel(tenantId!, id),
    onSuccess: async () => {
      toast.success("سند لغو شد");
      setConfirm(null);
      await invalidate();
    },
    onError: (e: Error) => toast.error(e.message),
  });

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

  const v = voucherQ.data!;
  const accountMap = new Map((accountsQ.data ?? []).map((a) => [a.id, `${a.code} — ${a.name}`]));
  const postable = (accountsQ.data ?? []).filter((a) => a.is_postable);
  const activeCostCenters = (costCentersQ.data ?? []).filter((c) => c.is_active);
  const activeProjects = (projectsQ.data ?? []).filter((p) => p.is_active);
  const isDraft = v.status === "draft";

  return (
    <div>
      <PageHeader
        title={`سند ${v.voucher_number}`}
        description={v.description || "جزئیات سند و اقدامات Posting Engine"}
        actions={
          <div className="flex flex-wrap gap-2">
            <Button type="button" variant="outline" onClick={() => router.push("/accounting/vouchers")}>
              بازگشت
            </Button>
            {isDraft ? (
              <Button type="button" variant="outline" onClick={() => setEditing((e) => !e)}>
                {editing ? "لغو ویرایش" : "ویرایش"}
              </Button>
            ) : null}
            {v.status === "draft" || v.status === "validated" ? (
              <Button type="button" variant="outline" disabled={validateM.isPending} onClick={() => validateM.mutate()}>
                اعتبارسنجی
              </Button>
            ) : null}
            {v.status === "draft" || v.status === "validated" ? (
              <Button type="button" onClick={() => setConfirm("post")}>
                ثبت قطعی
              </Button>
            ) : null}
            {v.status === "posted" ? (
              <Button type="button" variant="outline" onClick={() => setConfirm("reverse")}>
                برگشت
              </Button>
            ) : null}
            {v.status === "draft" || v.status === "validated" ? (
              <Button type="button" variant="danger" onClick={() => setConfirm("cancel")}>
                لغو
              </Button>
            ) : null}
          </div>
        }
      />

      <div className="mb-6 grid gap-4 sm:grid-cols-4">
        <Card>
          <CardContent className="pt-5">
            <p className="text-xs text-[var(--muted)]">وضعیت</p>
            <Badge className="mt-2" tone={v.status === "posted" ? "success" : "default"}>
              {v.status}
            </Badge>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-5">
            <p className="text-xs text-[var(--muted)]">تاریخ</p>
            <p className="mt-2 font-medium">
              <JalaliDateText value={v.voucher_date} />
            </p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-5">
            <p className="text-xs text-[var(--muted)]">جمع بدهکار</p>
            <p className="mt-2 font-medium">{formatMoney(v.total_debit)}</p>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="pt-5">
            <p className="text-xs text-[var(--muted)]">جمع بستانکار</p>
            <p className="mt-2 font-medium">{formatMoney(v.total_credit)}</p>
          </CardContent>
        </Card>
      </div>

      {isDraft && editing ? (
        <form className="space-y-4" onSubmit={editForm.handleSubmit((d) => updateM.mutate(d))}>
          <Card>
            <CardContent className="grid gap-4 pt-6 sm:grid-cols-2">
              <div>
                <Label>تاریخ</Label>
                <Controller
                  control={editForm.control}
                  name="voucher_date"
                  render={({ field }) => (
                    <DatePicker
                      className="mt-1"
                      value={field.value}
                      onChange={field.onChange}
                      onBlur={field.onBlur}
                      name={field.name}
                    />
                  )}
                />
                <FieldError>{editForm.formState.errors.voucher_date?.message}</FieldError>
              </div>
              <div>
                <Label>شرح</Label>
                <Input className="mt-1" {...editForm.register("description")} />
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardContent className="space-y-3 pt-6">
              <div className="flex items-center justify-between">
                <h2 className="font-semibold text-secondary">ردیف‌های سند</h2>
                <Button
                  type="button"
                  variant="outline"
                  size="sm"
                  onClick={() =>
                    append({
                      account_id: "",
                      debit: "0",
                      credit: "0",
                      description: "",
                      cost_center_id: "",
                      project_id: "",
                    })
                  }
                >
                  <Plus className="h-4 w-4" />
                  ردیف
                </Button>
              </div>
              {fields.map((field, index) => (
                <div
                  key={field.id}
                  className="grid gap-2 rounded-xl border border-[var(--border)] p-3 sm:grid-cols-12"
                >
                  <div className="sm:col-span-3">
                    <Label>حساب</Label>
                    <Select className="mt-1" {...editForm.register(`lines.${index}.account_id`)}>
                      <option value="">انتخاب</option>
                      {postable.map((a) => (
                        <option key={a.id} value={a.id}>
                          {a.code} — {a.name}
                        </option>
                      ))}
                    </Select>
                  </div>
                  <div className="sm:col-span-2">
                    <Label>بدهکار</Label>
                    <MoneyInput className="mt-1" {...editForm.register(`lines.${index}.debit`)} />
                  </div>
                  <div className="sm:col-span-2">
                    <Label>بستانکار</Label>
                    <MoneyInput className="mt-1" {...editForm.register(`lines.${index}.credit`)} />
                  </div>
                  <div className="sm:col-span-2">
                    <Label>مرکز هزینه</Label>
                    <Select className="mt-1" {...editForm.register(`lines.${index}.cost_center_id`)}>
                      <option value="">—</option>
                      {activeCostCenters.map((c) => (
                        <option key={c.id} value={c.id}>
                          {c.code} — {c.name}
                        </option>
                      ))}
                    </Select>
                  </div>
                  <div className="sm:col-span-2">
                    <Label>پروژه</Label>
                    <Select className="mt-1" {...editForm.register(`lines.${index}.project_id`)}>
                      <option value="">—</option>
                      {activeProjects.map((p) => (
                        <option key={p.id} value={p.id}>
                          {p.code} — {p.name}
                        </option>
                      ))}
                    </Select>
                  </div>
                  <div className="flex items-end sm:col-span-1">
                    <Button
                      type="button"
                      variant="ghost"
                      size="icon"
                      disabled={fields.length <= 2}
                      onClick={() => remove(index)}
                      aria-label="حذف ردیف"
                    >
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  </div>
                </div>
              ))}
              <FieldError>
                {editForm.formState.errors.lines?.message || editForm.formState.errors.lines?.root?.message}
              </FieldError>
            </CardContent>
          </Card>

          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setEditing(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={updateM.isPending}>
              ذخیره تغییرات
            </Button>
          </div>
        </form>
      ) : (
        <DataTable
          columns={[
            { key: "line_number", header: "#" },
            {
              key: "account_id",
              header: "حساب",
              render: (r) => accountMap.get(String(r.account_id)) || String(r.account_id),
            },
            { key: "debit", header: "بدهکار", render: (r) => formatMoney(String(r.debit)) },
            { key: "credit", header: "بستانکار", render: (r) => formatMoney(String(r.credit)) },
            { key: "description", header: "شرح" },
          ]}
          rows={(v.lines ?? []) as unknown as Record<string, unknown>[]}
        />
      )}

      <ConfirmDialog
        open={confirm === "post"}
        onClose={() => setConfirm(null)}
        title="ثبت قطعی سند؟"
        description="پس از ثبت، Journal Entry فقط از طریق Posting Engine ایجاد می‌شود و قابل ویرایش مستقیم نیست."
        confirmLabel="ثبت قطعی"
        loading={postM.isPending}
        onConfirm={() => postM.mutate()}
      />
      <ConfirmDialog
        open={confirm === "reverse"}
        onClose={() => setConfirm(null)}
        title="برگشت سند؟"
        description="یک سند معکوس از طریق Posting Engine ایجاد می‌شود."
        confirmLabel="برگشت"
        loading={reverseM.isPending}
        onConfirm={() => reverseM.mutate()}
      />
      <ConfirmDialog
        open={confirm === "cancel"}
        onClose={() => setConfirm(null)}
        title="لغو سند؟"
        description="سند پیش‌نویس لغو می‌شود و دیگر قابل ثبت نیست."
        confirmLabel="لغو سند"
        danger
        loading={cancelM.isPending}
        onConfirm={() => cancelM.mutate()}
      />
    </div>
  );
}
