"use client";

import { useMemo, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { Download, RefreshCw, Search } from "lucide-react";
import { Button, Input, Select } from "@/components/ds";
import { useTenantId } from "@/hooks/useTenantId";
import { PaymentStatusChip } from "@/modules/payment/components/PaymentStatusChip";
import {
  PaymentEmptyState,
  PaymentPageError,
  PaymentPageLoader,
  exportToCsv,
} from "@/modules/payment/pages/shared";
import type { PaymentRecord } from "@/modules/payment/types";

type Column = {
  key: string;
  header: string;
  type?: "status" | "datetime" | "text";
  render?: (row: PaymentRecord) => React.ReactNode;
};

type Props = {
  title: string;
  description?: string;
  resourceKey: string;
  columns: Column[];
  fetcher: (tenantId: string) => Promise<PaymentRecord[]>;
  filterKey?: string;
  detailHref?: (row: PaymentRecord) => string | null;
  rowActions?: React.ReactNode | ((row: PaymentRecord, refresh: () => void) => React.ReactNode);
  headerActions?: React.ReactNode;
};

const PAGE_SIZE = 10;

export function PaymentListPage({
  title,
  description,
  resourceKey,
  columns,
  fetcher,
  filterKey = "status",
  detailHref,
  rowActions,
  headerActions,
}: Props) {
  const { tenantId } = useTenantId();
  const [search, setSearch] = useState("");
  const [filter, setFilter] = useState("");
  const [sortKey, setSortKey] = useState(columns[0]?.key || "created_at");
  const [sortDir, setSortDir] = useState<"asc" | "desc">("desc");
  const [page, setPage] = useState(1);

  const q = useQuery({
    queryKey: ["payment", tenantId, resourceKey],
    queryFn: () => fetcher(tenantId!),
    enabled: !!tenantId,
  });

  const rows = useMemo(() => {
    let data = [...(q.data ?? [])];
    if (filter) data = data.filter((r) => String(r[filterKey] ?? "") === filter);
    if (search.trim()) {
      const s = search.trim().toLowerCase();
      data = data.filter((r) => JSON.stringify(r).toLowerCase().includes(s));
    }
    data.sort((a, b) => {
      const av = String(a[sortKey] ?? "");
      const bv = String(b[sortKey] ?? "");
      return sortDir === "asc" ? av.localeCompare(bv) : bv.localeCompare(av);
    });
    return data;
  }, [q.data, filter, filterKey, search, sortKey, sortDir]);

  const filterOptions = useMemo(() => {
    const set = new Set((q.data ?? []).map((r) => String(r[filterKey] ?? "")).filter(Boolean));
    return Array.from(set);
  }, [q.data, filterKey]);

  const totalPages = Math.max(1, Math.ceil(rows.length / PAGE_SIZE));
  const pageRows = rows.slice((page - 1) * PAGE_SIZE, page * PAGE_SIZE);

  if (!tenantId || q.isLoading) return <PaymentPageLoader />;
  if (q.isError) return <PaymentPageError error={q.error} onRetry={() => q.refetch()} />;

  return (
    <div className="space-y-4">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
        <div>
          <h1 className="text-xl font-semibold text-secondary">{title}</h1>
          {description ? <p className="mt-1 text-sm text-[var(--muted)]">{description}</p> : null}
        </div>
        <div className="flex flex-wrap gap-2">
          {headerActions}
          <Button variant="outline" size="sm" onClick={() => q.refetch()} aria-label="بازنشانی">
            <RefreshCw className="h-4 w-4" />
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={() =>
              exportToCsv(
                resourceKey,
                rows,
                columns.map((c) => c.key)
              )
            }
          >
            <Download className="ml-1 h-4 w-4" />
            خروجی
          </Button>
        </div>
      </div>

      <div className="flex flex-col gap-2 sm:flex-row">
        <div className="relative flex-1">
          <Search className="pointer-events-none absolute right-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--muted)]" />
          <Input
            className="pr-9"
            placeholder="جستجو…"
            value={search}
            onChange={(e) => {
              setSearch(e.target.value);
              setPage(1);
            }}
            aria-label="جستجو"
          />
        </div>
        <Select
          value={filter}
          onChange={(e) => {
            setFilter(e.target.value);
            setPage(1);
          }}
          aria-label="فیلتر وضعیت"
        >
          <option value="">همه وضعیت‌ها</option>
          {filterOptions.map((o) => (
            <option key={o} value={o}>
              {o}
            </option>
          ))}
        </Select>
        <Select
          value={`${sortKey}:${sortDir}`}
          onChange={(e) => {
            const [k, d] = e.target.value.split(":");
            setSortKey(k);
            setSortDir(d as "asc" | "desc");
          }}
          aria-label="مرتب‌سازی"
        >
          {columns.map((c) => (
            <option key={`${c.key}-desc`} value={`${c.key}:desc`}>
              {c.header} ↓
            </option>
          ))}
          {columns.map((c) => (
            <option key={`${c.key}-asc`} value={`${c.key}:asc`}>
              {c.header} ↑
            </option>
          ))}
        </Select>
      </div>

      {rows.length === 0 ? (
        <PaymentEmptyState />
      ) : (
        <div className="overflow-x-auto rounded-xl border border-[var(--border)] bg-[var(--surface)]">
          <table className="min-w-full text-sm">
            <thead className="bg-[var(--surface-muted)] text-[var(--muted)]">
              <tr>
                {columns.map((c) => (
                  <th key={c.key} className="px-3 py-2 text-right font-medium">
                    {c.header}
                  </th>
                ))}
                {(detailHref || rowActions) && (
                  <th className="px-3 py-2 text-right font-medium">عملیات</th>
                )}
              </tr>
            </thead>
            <tbody>
              {pageRows.map((row, idx) => (
                <tr key={String(row.id ?? idx)} className="border-t border-[var(--border)]">
                  {columns.map((c) => (
                    <td key={c.key} className="px-3 py-2 text-secondary">
                      {c.render
                        ? c.render(row)
                        : c.type === "status"
                          ? <PaymentStatusChip status={String(row[c.key] ?? "")} />
                          : c.type === "datetime" && row[c.key]
                            ? new Date(String(row[c.key])).toLocaleString("fa-IR")
                            : String(row[c.key] ?? "—")}
                    </td>
                  ))}
                  {(detailHref || rowActions) && (
                    <td className="px-3 py-2">
                      <div className="flex flex-wrap gap-2">
                        {detailHref?.(row) ? (
                          <a
                            href={detailHref(row)!}
                            className="text-xs font-medium text-[var(--payment-accent,#0d9488)] hover:underline"
                          >
                            جزئیات
                          </a>
                        ) : null}
                        {typeof rowActions === "function"
                          ? rowActions(row, () => q.refetch())
                          : rowActions}
                      </div>
                    </td>
                  )}
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      <div className="flex items-center justify-between text-xs text-[var(--muted)]">
        <span>
          {rows.length} مورد — صفحه {page} از {totalPages}
        </span>
        <div className="flex gap-2">
          <Button
            size="sm"
            variant="outline"
            disabled={page <= 1}
            onClick={() => setPage((p) => p - 1)}
          >
            قبلی
          </Button>
          <Button
            size="sm"
            variant="outline"
            disabled={page >= totalPages}
            onClick={() => setPage((p) => p + 1)}
          >
            بعدی
          </Button>
        </div>
      </div>
    </div>
  );
}
