"use client";

import { useState } from "react";
import { useForm, type FieldValues, type DefaultValues } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { toast } from "sonner";
import { Plus, Pencil, Trash2, Download } from "lucide-react";
import { z } from "zod";
import {
  Button,
  Dialog,
  Input,
  EmptyState,
  FormField,
  ConfirmDialog,
  Select,
} from "@/components/ds";
import { SportsCenterTablePage } from "@/modules/sports-center/design-system";
import { SportsCenterPageLoader, SportsCenterPageError, exportToCsv } from "@/modules/sports-center/pages/shared";
import { useTenantId } from "@/hooks/useTenantId";
import { useSportsCenterCapabilities } from "@/modules/sports-center/hooks/useSportsCenterCapabilities";
import { SportsCenterStatusChip } from "@/modules/sports-center/design-system";
import { SportsCenterFeatureGate } from "@/modules/sports-center/components/SportsCenterFeatureGate";

export type SportsCenterFieldConfig = {
  name: string;
  label: string;
  type?: "text" | "number" | "select";
  options?: { value: string; label: string }[];
  required?: boolean;
};

export type SportsCenterColumnConfig = {
  key: string;
  header: string;
  type?: "status" | "datetime" | "text";
  render?: (row: Record<string, unknown>) => React.ReactNode;
};

type ApiResource = {
  list: (tenantId: string, params?: Record<string, string | number | undefined | null>) => Promise<Record<string, unknown>[]>;
  create?: (tenantId: string, body: Record<string, unknown>) => Promise<unknown>;
  update?: (tenantId: string, id: string, body: Record<string, unknown>) => Promise<unknown>;
  remove?: (tenantId: string, id: string) => Promise<unknown>;
};

export type SportsCenterListConfig = {
  title: string;
  description?: string;
  breadcrumb?: string;
  resourceKey: string;
  feature?: string;
  permission?: string;
  api: ApiResource;
  columns: SportsCenterColumnConfig[];
  createFields?: SportsCenterFieldConfig[];
  editFields?: SportsCenterFieldConfig[];
  filterDeleted?: boolean;
  readOnly?: boolean;
  createOnly?: boolean;
  listQueryParam?: string;
};

function buildSchema(fields: SportsCenterFieldConfig[]) {
  const shape: Record<string, z.ZodTypeAny> = {};
  for (const f of fields) {
    shape[f.name] = f.required
      ? z.string().min(1, `${f.label} الزامی است`)
      : z.string().optional();
  }
  return z.object(shape);
}

function renderCell(col: SportsCenterColumnConfig, row: Record<string, unknown>) {
  if (col.render) return col.render(row);
  const val = row[col.key];
  if (col.type === "status" && val) return <SportsCenterStatusChip status={String(val)} />;
  if (col.type === "datetime" && val) {
    try {
      return new Date(String(val)).toLocaleString("fa-IR");
    } catch {
      return String(val);
    }
  }
  return val != null ? String(val) : "—";
}

export function createSportsCenterListPage(config: SportsCenterListConfig) {
  return function SportsCenterListPage() {
    const { tenantId } = useTenantId();
    const qc = useQueryClient();
    const caps = useSportsCenterCapabilities();
    const [createOpen, setCreateOpen] = useState(false);
    const [editRow, setEditRow] = useState<Record<string, unknown> | null>(null);
    const [deleteId, setDeleteId] = useState<string | null>(null);
    const [page, setPage] = useState(1);
    const [listFilter, setListFilter] = useState("");
    const pageSize = 20;

    const createFields = config.createFields ?? [];
    const editFields = config.editFields ?? createFields;
    const createSchema = buildSchema(createFields);
    const editSchema = buildSchema(editFields);

    const listParams: Record<string, string | number | undefined | null> = { page, page_size: pageSize };
    if (config.listQueryParam && listFilter.trim()) {
      listParams[config.listQueryParam] = listFilter.trim();
    }

    const listQ = useQuery({
      queryKey: ["sports-center", tenantId, config.resourceKey, page, listFilter],
      queryFn: () => config.api.list(tenantId!, listParams),
      enabled: !!tenantId && (!config.listQueryParam || !!listFilter.trim()),
    });

    const createForm = useForm({
      resolver: zodResolver(createSchema),
      defaultValues: Object.fromEntries(createFields.map((f) => [f.name, ""])) as DefaultValues<FieldValues>,
    });
    const editForm = useForm({ resolver: zodResolver(editSchema) });

    const invalidate = () =>
      qc.invalidateQueries({ queryKey: ["sports-center", tenantId, config.resourceKey] });

    const createM = useMutation({
      mutationFn: (d: FieldValues) => config.api.create!(tenantId!, d as Record<string, unknown>),
      onSuccess: async () => {
        toast.success("رکورد ایجاد شد");
        setCreateOpen(false);
        createForm.reset();
        await invalidate();
      },
      onError: (e: Error) => toast.error(e.message),
    });

    const updateM = useMutation({
      mutationFn: (d: FieldValues) => config.api.update!(tenantId!, String(editRow!.id), d as Record<string, unknown>),
      onSuccess: async () => {
        toast.success("به‌روزرسانی شد");
        setEditRow(null);
        await invalidate();
      },
      onError: (e: Error) => toast.error(e.message),
    });

    const deleteM = useMutation({
      mutationFn: (id: string) => config.api.remove!(tenantId!, id),
      onSuccess: async () => {
        toast.success("حذف شد");
        setDeleteId(null);
        await invalidate();
      },
      onError: (e: Error) => toast.error(e.message),
    });

    if (!tenantId || listQ.isLoading || caps.isLoading) return <SportsCenterPageLoader />;
    if (config.listQueryParam && !listFilter.trim()) {
      return (
        <div className="mx-auto max-w-md space-y-4">
          <SportsCenterTablePage
            title={config.title}
            description={config.description ?? `شناسه ${config.listQueryParam} را وارد کنید`}
            breadcrumb={config.breadcrumb ?? config.title}
            columns={[]}
            rows={[]}
            empty={
              <div className="space-y-3">
                <FormField label={config.listQueryParam}>
                  <Input
                    value={listFilter}
                    onChange={(e) => setListFilter(e.target.value)}
                    placeholder={`${config.listQueryParam}…`}
                  />
                </FormField>
                <Button onClick={() => listQ.refetch()} disabled={!listFilter.trim()}>
                  بارگذاری
                </Button>
              </div>
            }
          />
        </div>
      );
    }
    if (listQ.error) return <SportsCenterPageError error={listQ.error} onRetry={() => listQ.refetch()} />;

    let rows = listQ.data ?? [];
    if (config.filterDeleted) rows = rows.filter((r) => !r.is_deleted);

    const canUpdate = !config.readOnly && !config.createOnly && !!config.api.update;
    const canDelete = !config.readOnly && !config.createOnly && !!config.api.remove;
    const canCreate = !!config.api.create && createFields.length > 0;

    const tableColumns = [
      ...config.columns.map((c) => ({
        key: c.key,
        header: c.header,
        render: (row: Record<string, unknown>) => renderCell(c, row),
      })),
      ...(canUpdate || canDelete
        ? [
            {
              key: "actions",
              header: "عملیات",
              searchable: false as const,
              render: (row: Record<string, unknown>) => (
                <div className="flex gap-1">
                  {canUpdate ? (
                    <Button
                      variant="ghost"
                      size="icon"
                      aria-label="ویرایش"
                      onClick={() => {
                        setEditRow(row);
                        editForm.reset(Object.fromEntries(editFields.map((f) => [f.name, row[f.name] ?? ""])));
                      }}
                    >
                      <Pencil className="h-4 w-4" />
                    </Button>
                  ) : null}
                  {canDelete ? (
                    <Button variant="ghost" size="icon" aria-label="حذف" onClick={() => setDeleteId(String(row.id))}>
                      <Trash2 className="h-4 w-4" />
                    </Button>
                  ) : null}
                </div>
              ),
            },
          ]
        : []),
    ];

    const body = (
      <SportsCenterTablePage
        title={config.title}
        description={config.description}
        breadcrumb={config.breadcrumb ?? config.title}
        columns={tableColumns}
        rows={rows}
        actions={
          canCreate ? (
            <Button onClick={() => setCreateOpen(true)}>
              <Plus className="h-4 w-4" />
              جدید
            </Button>
          ) : undefined
        }
        toolbar={
          <div className="flex flex-wrap items-center gap-2">
            {config.listQueryParam ? (
              <Input
                value={listFilter}
                onChange={(e) => setListFilter(e.target.value)}
                placeholder={config.listQueryParam}
                className="w-40"
              />
            ) : null}
            <Button
              variant="outline"
              size="sm"
              onClick={() => exportToCsv(config.title, rows, config.columns.map((c) => c.key))}
            >
              <Download className="h-4 w-4" />
              خروجی
            </Button>
            <Button variant="outline" size="sm" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>
              قبلی
            </Button>
            <span className="text-xs text-[var(--muted)]">صفحه {page}</span>
            <Button
              variant="outline"
              size="sm"
              disabled={rows.length < pageSize}
              onClick={() => setPage((p) => p + 1)}
            >
              بعدی
            </Button>
          </div>
        }
        empty={
          <EmptyState
            title="موردی یافت نشد"
            action={canCreate ? <Button onClick={() => setCreateOpen(true)}>ایجاد اولین رکورد</Button> : undefined}
          />
        }
      />
    );

    const pageContent = config.feature ? (
      <SportsCenterFeatureGate feature={config.feature} capabilities={caps.data}>
        {body}
      </SportsCenterFeatureGate>
    ) : (
      body
    );

    return (
      <>
        {pageContent}
        {canCreate ? (
          <Dialog open={createOpen} onClose={() => setCreateOpen(false)} title={`${config.title} — جدید`}>
            <form className="space-y-3" onSubmit={createForm.handleSubmit((d) => createM.mutate(d))}>
              {createFields.map((f) => (
                <FormField key={f.name} label={f.label}>
                  {f.type === "select" && f.options ? (
                    <Select {...createForm.register(f.name)}>
                      {f.options.map((o) => (
                        <option key={o.value} value={o.value}>
                          {o.label}
                        </option>
                      ))}
                    </Select>
                  ) : (
                    <Input type={f.type ?? "text"} {...createForm.register(f.name)} />
                  )}
                </FormField>
              ))}
              <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>
        ) : null}
        {editRow && canUpdate ? (
          <Dialog open={!!editRow} onClose={() => setEditRow(null)} title={`${config.title} — ویرایش`}>
            <form className="space-y-3" onSubmit={editForm.handleSubmit((d) => updateM.mutate(d))}>
              {editFields.map((f) => (
                <FormField key={f.name} label={f.label}>
                  <Input {...editForm.register(f.name)} />
                </FormField>
              ))}
              <div className="flex justify-end gap-2">
                <Button type="button" variant="outline" onClick={() => setEditRow(null)}>
                  انصراف
                </Button>
                <Button type="submit" disabled={updateM.isPending}>
                  ذخیره
                </Button>
              </div>
            </form>
          </Dialog>
        ) : null}
        <ConfirmDialog
          open={!!deleteId}
          onClose={() => setDeleteId(null)}
          onConfirm={() => deleteId && deleteM.mutate(deleteId)}
          title="حذف رکورد"
          description="آیا از حذف این رکورد مطمئن هستید؟"
          confirmLabel="حذف"
          danger
        />
      </>
    );
  };
}
