"use client";

import { 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 { Calendar, 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,
  Tabs,
  FormField,
  Select,
  MoneyInput,
} from "@/src/shared/ui";

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

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

const depreciateSchema = z.object({
  expense_account_id: z.string().min(1, "حساب هزینه را انتخاب کنید"),
  accumulated_account_id: z.string().min(1, "حساب استهلاک انباشته را انتخاب کنید"),
});

type AssetRow = { id: string; code: string; name: string; status: string };
type TabId = "categories" | "assets";

export function AssetsPage() {
  const { tenantId } = useTenantId();
  const qc = useQueryClient();
  const [tab, setTab] = useState<TabId>("assets");
  const [categoryOpen, setCategoryOpen] = useState(false);
  const [assetOpen, setAssetOpen] = useState(false);
  const [depreciateAsset, setDepreciateAsset] = useState<AssetRow | null>(null);
  const [scheduleAsset, setScheduleAsset] = useState<AssetRow | null>(null);

  const categoriesQ = useQuery({
    queryKey: ["accounting", tenantId, "asset-categories"],
    queryFn: () => accountingApi.assets.listCategories(tenantId!),
    enabled: !!tenantId,
  });
  const assetsQ = useQuery({
    queryKey: ["accounting", tenantId, "assets"],
    queryFn: () => accountingApi.assets.list(tenantId!),
    enabled: !!tenantId,
  });
  const accountsQ = useQuery({
    queryKey: ["accounting", tenantId, "accounts"],
    queryFn: () => accountingApi.accounts.list(tenantId!),
    enabled: !!tenantId,
  });
  const scheduleQ = useQuery({
    queryKey: ["accounting", tenantId, "asset-schedule", scheduleAsset?.id],
    queryFn: () => accountingApi.assets.schedule(tenantId!, scheduleAsset!.id),
    enabled: !!tenantId && !!scheduleAsset,
  });

  const categoryForm = useForm<z.infer<typeof categorySchema>>({
    resolver: zodResolver(categorySchema),
    defaultValues: { code: "", name: "", default_useful_life_months: 60 },
  });
  const assetForm = useForm<z.infer<typeof assetSchema>>({
    resolver: zodResolver(assetSchema),
    defaultValues: { code: "", name: "", category_id: "", acquisition_cost: "0", residual_value: "0" },
  });
  const depreciateForm = useForm<z.infer<typeof depreciateSchema>>({
    resolver: zodResolver(depreciateSchema),
    defaultValues: { expense_account_id: "", accumulated_account_id: "" },
  });

  const postableAccounts = (accountsQ.data ?? []).filter((a) => a.is_postable && a.status === "active");

  const invalidateCategories = () =>
    qc.invalidateQueries({ queryKey: ["accounting", tenantId, "asset-categories"] });
  const invalidateAssets = () => qc.invalidateQueries({ queryKey: ["accounting", tenantId, "assets"] });

  const createCategoryM = useMutation({
    mutationFn: (d: z.infer<typeof categorySchema>) =>
      accountingApi.assets.createCategory(tenantId!, {
        code: d.code,
        name: d.name,
        default_useful_life_months: d.default_useful_life_months,
      }),
    onSuccess: async () => {
      toast.success("دسته‌بندی ایجاد شد");
      setCategoryOpen(false);
      categoryForm.reset();
      await invalidateCategories();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const createAssetM = useMutation({
    mutationFn: (d: z.infer<typeof assetSchema>) =>
      accountingApi.assets.create(tenantId!, {
        code: d.code,
        name: d.name,
        category_id: d.category_id || undefined,
        acquisition_cost: d.acquisition_cost,
        residual_value: d.residual_value,
      }),
    onSuccess: async () => {
      toast.success("دارایی ایجاد شد");
      setAssetOpen(false);
      assetForm.reset();
      await invalidateAssets();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const activateM = useMutation({
    mutationFn: (id: string) => accountingApi.assets.activate(tenantId!, id),
    onSuccess: async () => {
      toast.success("دارایی فعال شد");
      await invalidateAssets();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const depreciateM = useMutation({
    mutationFn: (d: z.infer<typeof depreciateSchema>) =>
      accountingApi.assets.depreciate(tenantId!, depreciateAsset!.id, d),
    onSuccess: async (res) => {
      toast.success(`استهلاک ثبت شد — مبلغ ${formatMoney(res.amount)}`);
      setDepreciateAsset(null);
      depreciateForm.reset();
      await invalidateAssets();
    },
    onError: (e: Error) => toast.error(e.message),
  });

  if (!tenantId) return <LoadingState />;
  const loading = categoriesQ.isLoading || assetsQ.isLoading || accountsQ.isLoading;
  if (loading) return <LoadingState />;
  const err = categoriesQ.error || assetsQ.error || accountsQ.error;
  if (err) {
    return (
      <ErrorState
        message={err instanceof Error ? err.message : "خطا"}
        onRetry={() => {
          void categoriesQ.refetch();
          void assetsQ.refetch();
          void accountsQ.refetch();
        }}
      />
    );
  }

  const statusTone = (s: string) =>
    s === "active" ? "success" : s === "draft" ? "default" : "warning";

  const tabAction =
    tab === "categories" ? (
      <Button onClick={() => setCategoryOpen(true)}>
        <Plus className="h-4 w-4" />
        دسته جدید
      </Button>
    ) : (
      <Button onClick={() => setAssetOpen(true)}>
        <Plus className="h-4 w-4" />
        دارایی جدید
      </Button>
    );

  const scheduleRows = (scheduleQ.data?.schedule ?? []) as Record<string, unknown>[];
  const scheduleColumns =
    scheduleRows.length > 0
      ? Object.keys(scheduleRows[0]).map((k) => ({ key: k, header: k }))
      : [{ key: "period", header: "دوره" }];

  return (
    <div>
      <PageHeader
        title="دارایی‌های ثابت"
        description="دسته‌بندی، ثبت، فعال‌سازی و استهلاک دارایی."
        actions={tabAction}
      />

      <Tabs
        className="mb-6"
        value={tab}
        onChange={(id) => setTab(id as TabId)}
        items={[
          { id: "assets", label: "دارایی‌ها" },
          { id: "categories", label: "دسته‌بندی‌ها" },
        ]}
      />

      {tab === "categories" && (
        <DataTable
          columns={[
            { key: "code", header: "کد" },
            { key: "name", header: "نام" },
            {
              key: "default_useful_life_months",
              header: "عمر مفید (ماه)",
              render: (r) => String(r.default_useful_life_months ?? "—"),
            },
          ]}
          rows={(categoriesQ.data ?? []) as unknown as Record<string, unknown>[]}
          empty={
            <EmptyState action={<Button onClick={() => setCategoryOpen(true)}>ایجاد دسته</Button>} />
          }
        />
      )}

      {tab === "assets" && (
        <DataTable
          columns={[
            { key: "code", header: "کد" },
            { key: "name", header: "نام" },
            {
              key: "status",
              header: "وضعیت",
              render: (r) => <Badge tone={statusTone(String(r.status))}>{String(r.status)}</Badge>,
            },
            {
              key: "actions",
              header: "عملیات",
              render: (r) => {
                const row = r as unknown as AssetRow;
                return (
                  <div className="flex flex-wrap gap-1">
                    {row.status !== "active" && (
                      <Button
                        type="button"
                        size="sm"
                        variant="outline"
                        disabled={activateM.isPending}
                        onClick={() => activateM.mutate(row.id)}
                      >
                        فعال‌سازی
                      </Button>
                    )}
                    {row.status === "active" && (
                      <Button
                        type="button"
                        size="sm"
                        variant="outline"
                        onClick={() => {
                          setDepreciateAsset(row);
                          depreciateForm.reset();
                        }}
                      >
                        استهلاک
                      </Button>
                    )}
                    <Button
                      type="button"
                      size="sm"
                      variant="secondary"
                      onClick={() => setScheduleAsset(row)}
                    >
                      <Calendar className="h-3.5 w-3.5" />
                      برنامه
                    </Button>
                  </div>
                );
              },
            },
          ]}
          rows={(assetsQ.data ?? []) as unknown as Record<string, unknown>[]}
          empty={<EmptyState action={<Button onClick={() => setAssetOpen(true)}>ایجاد دارایی</Button>} />}
        />
      )}

      <Dialog open={categoryOpen} onClose={() => setCategoryOpen(false)} title="دسته‌بندی جدید">
        <form className="space-y-3" onSubmit={categoryForm.handleSubmit((d) => createCategoryM.mutate(d))}>
          <FormField label="کد" error={categoryForm.formState.errors.code?.message}>
            <Input {...categoryForm.register("code")} />
          </FormField>
          <FormField label="نام" error={categoryForm.formState.errors.name?.message}>
            <Input {...categoryForm.register("name")} />
          </FormField>
          <FormField label="عمر مفید پیش‌فرض (ماه)">
            <Input
              type="number"
              {...categoryForm.register("default_useful_life_months", { valueAsNumber: true })}
            />
          </FormField>
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setCategoryOpen(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={createCategoryM.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Dialog>

      <Dialog open={assetOpen} onClose={() => setAssetOpen(false)} title="دارایی جدید">
        <form className="space-y-3" onSubmit={assetForm.handleSubmit((d) => createAssetM.mutate(d))}>
          <FormField label="کد" error={assetForm.formState.errors.code?.message}>
            <Input {...assetForm.register("code")} />
          </FormField>
          <FormField label="نام" error={assetForm.formState.errors.name?.message}>
            <Input {...assetForm.register("name")} />
          </FormField>
          <FormField label="دسته‌بندی">
            <Select {...assetForm.register("category_id")}>
              <option value="">بدون دسته</option>
              {(categoriesQ.data ?? []).map((c) => (
                <option key={c.id} value={c.id}>
                  {c.code} — {c.name}
                </option>
              ))}
            </Select>
          </FormField>
          <FormField label="بهای تمام‌شده">
            <MoneyInput {...assetForm.register("acquisition_cost")} />
          </FormField>
          <FormField label="ارزش اسقاط">
            <MoneyInput {...assetForm.register("residual_value")} />
          </FormField>
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setAssetOpen(false)}>
              انصراف
            </Button>
            <Button type="submit" disabled={createAssetM.isPending}>
              ذخیره
            </Button>
          </div>
        </form>
      </Dialog>

      <Dialog
        open={!!depreciateAsset}
        onClose={() => setDepreciateAsset(null)}
        title="ثبت استهلاک"
        description={depreciateAsset ? `${depreciateAsset.code} — ${depreciateAsset.name}` : undefined}
      >
        <form className="space-y-3" onSubmit={depreciateForm.handleSubmit((d) => depreciateM.mutate(d))}>
          <FormField label="حساب هزینه استهلاک" error={depreciateForm.formState.errors.expense_account_id?.message}>
            <Select {...depreciateForm.register("expense_account_id")}>
              <option value="">انتخاب حساب</option>
              {postableAccounts.map((a) => (
                <option key={a.id} value={a.id}>
                  {a.code} — {a.name}
                </option>
              ))}
            </Select>
          </FormField>
          <FormField
            label="حساب استهلاک انباشته"
            error={depreciateForm.formState.errors.accumulated_account_id?.message}
          >
            <Select {...depreciateForm.register("accumulated_account_id")}>
              <option value="">انتخاب حساب</option>
              {postableAccounts.map((a) => (
                <option key={a.id} value={a.id}>
                  {a.code} — {a.name}
                </option>
              ))}
            </Select>
          </FormField>
          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => setDepreciateAsset(null)}>
              انصراف
            </Button>
            <Button type="submit" disabled={depreciateM.isPending}>
              ثبت استهلاک
            </Button>
          </div>
        </form>
      </Dialog>

      <Drawer
        open={!!scheduleAsset}
        onClose={() => setScheduleAsset(null)}
        title="برنامه استهلاک"
        description={scheduleAsset ? `${scheduleAsset.code} — ${scheduleAsset.name}` : undefined}
        width="lg"
      >
        {scheduleQ.isLoading ? (
          <LoadingState label="بارگذاری برنامه…" />
        ) : scheduleQ.error ? (
          <ErrorState message={scheduleQ.error.message} onRetry={() => scheduleQ.refetch()} />
        ) : (
          <DataTable
            columns={scheduleColumns.map((c) => ({
              ...c,
              render: (r) => {
                const v = r[c.key];
                if (typeof v === "number" || (typeof v === "string" && /^\d/.test(v))) {
                  return formatMoney(String(v));
                }
                return String(v ?? "—");
              },
            }))}
            rows={scheduleRows}
            empty={<EmptyState title="برنامه‌ای موجود نیست" />}
          />
        )}
      </Drawer>
    </div>
  );
}
