"use client";

import { FormEvent, ReactNode, useMemo, useState } from "react";
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight, RotateCcw, Search } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { cn } from "@/lib/utils";

export type SearchFieldConfig = {
  key: string;
  label: string;
  type?: "text" | "select";
  placeholder?: string;
  defaultValue?: string;
  options?: Array<{ value: string; label: string }>;
  className?: string;
};

export type TableColumnConfig<T extends Record<string, unknown> = Record<string, unknown>> = {
  key: keyof T | string;
  label: string;
  width?: string;
  minWidth?: string;
  align?: "left" | "center" | "right";
  className?: string;
  headerClassName?: string;
  ellipsis?: boolean;
  render?: (value: unknown, row: T, index: number) => ReactNode;
};

export type PaginationConfig = {
  page: number;
  size: number;
  total: number;
  totalPages?: number;
  hasNext?: boolean;
  hasPrev?: boolean;
};

type PageHeaderProps<T extends Record<string, unknown> = Record<string, unknown>> = {
  title: string;
  description?: string;
  actions?: ReactNode;
  searchFields?: SearchFieldConfig[];
  columns?: TableColumnConfig<T>[];
  data?: T[];
  loading?: boolean;
  emptyText?: string;
  rowKey?: keyof T | ((row: T, index: number) => string);
  pagination?: PaginationConfig;
  sizeOptions?: number[];
  onSearch?: (filters: Record<string, string>) => void;
  onReset?: () => void;
  onPageChange?: (page: number) => void;
  onSizeChange?: (size: number) => void;
  className?: string;
};

function getInitialFilters(fields: SearchFieldConfig[]) {
  return fields.reduce<Record<string, string>>((result, field) => {
    result[field.key] = field.defaultValue ?? "";
    return result;
  }, {});
}

function getCellText(value: unknown) {
  if (value === null || value === undefined || value === "") return "-";
  return String(value);
}

export function PageHeader<T extends Record<string, unknown> = Record<string, unknown>>({
  title,
  description,
  actions,
  searchFields = [],
  columns = [],
  data = [],
  loading = false,
  emptyText = "暂无数据",
  rowKey,
  pagination,
  sizeOptions = [10, 20, 50, 100],
  onSearch,
  onReset,
  onPageChange,
  onSizeChange,
  className,
}: PageHeaderProps<T>) {
  const [filters, setFilters] = useState<Record<string, string>>(() => getInitialFilters(searchFields));
  const showSearch = searchFields.length > 0;
  const showTable = columns.length > 0;
  const totalPages = Math.max(1, pagination?.totalPages ?? Math.ceil((pagination?.total ?? 0) / (pagination?.size || 1)));
  const currentPage = pagination?.page ?? 1;
  const pageSize = pagination?.size ?? sizeOptions[0];
  const hasPrev = pagination?.hasPrev ?? currentPage > 1;
  const hasNext = pagination?.hasNext ?? currentPage < totalPages;

  const tableMinWidth = useMemo(() => {
    if (!columns.length) return undefined;
    const total = columns.reduce((sum, column) => {
      const raw = column.width || column.minWidth || "160px";
      const number = Number.parseInt(raw, 10);
      return sum + (Number.isFinite(number) ? number : 160);
    }, 0);
    return `${Math.max(total, 720)}px`;
  }, [columns]);

  const updateFilter = (key: string, value: string) => {
    setFilters((current) => ({ ...current, [key]: value }));
  };

  const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    onSearch?.(filters);
  };

  const handleReset = () => {
    const nextFilters = getInitialFilters(searchFields);
    setFilters(nextFilters);
    onReset?.();
    onSearch?.(nextFilters);
  };

  const getRowKey = (row: T, index: number) => {
    if (typeof rowKey === "function") return rowKey(row, index);
    if (rowKey) return String(row[rowKey] ?? index);
    return String(row.id ?? row.key ?? index);
  };

  const alignClass = (align?: TableColumnConfig<T>["align"]) => {
    if (align === "center") return "text-center";
    if (align === "right") return "text-right";
    return "text-left";
  };

  return (
    <section className={cn("space-y-4", className)}>
      <div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
        <div className="min-w-0 space-y-1">
          <h2 className="truncate text-2xl font-black tracking-tight text-foreground" title={title}>{title}</h2>
          {description ? <p className="text-sm leading-6 text-muted-foreground">{description}</p> : null}
        </div>
        {actions ? <div className="shrink-0">{actions}</div> : null}
      </div>

      {showSearch ? (
        <form onSubmit={handleSubmit} className="rounded-2xl border border-border bg-card p-4 shadow-sm">
          <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
            {searchFields.map((field) => (
              <label key={field.key} className={cn("grid gap-1.5", field.className)}>
                <span className="text-xs font-semibold text-muted-foreground">{field.label}</span>
                {field.type === "select" ? (
                  <Select value={filters[field.key] ?? ""} onValueChange={(value) => updateFilter(field.key, value)}>
                    <SelectTrigger className="bg-background">
                      <SelectValue placeholder={field.placeholder ?? `请选择${field.label}`} />
                    </SelectTrigger>
                    <SelectContent>
                      {(field.options ?? []).map((option) => (
                        <SelectItem key={option.value} value={option.value}>{option.label}</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                ) : (
                  <Input value={filters[field.key] ?? ""} onChange={(event) => updateFilter(field.key, event.target.value)} placeholder={field.placeholder} />
                )}
              </label>
            ))}
          </div>
          <div className="mt-4 flex flex-wrap justify-end gap-2">
            <Button type="button" variant="outline" onClick={handleReset}>
              <RotateCcw className="h-4 w-4" />
              重置
            </Button>
            <Button type="submit">
              <Search className="h-4 w-4" />
              查询
            </Button>
          </div>
        </form>
      ) : null}

      {showTable ? (
        <div className="overflow-hidden rounded-2xl border border-border bg-card shadow-sm">
          <div className="overflow-x-auto">
            <Table className="table-fixed" style={{ minWidth: tableMinWidth }}>
              <TableHeader>
                <TableRow className="bg-muted/70 hover:bg-muted/70">
                  {columns.map((column) => (
                    <TableHead
                      key={String(column.key)}
                      className={cn("h-11 whitespace-nowrap px-4 text-xs font-bold text-muted-foreground", alignClass(column.align), column.headerClassName)}
                      style={{ width: column.width, minWidth: column.minWidth }}
                      title={column.label}
                    >
                      <span className="block truncate">{column.label}</span>
                    </TableHead>
                  ))}
                </TableRow>
              </TableHeader>
              <TableBody>
                {loading ? (
                  <TableRow>
                    <TableCell colSpan={columns.length} className="h-32 text-center text-sm text-muted-foreground">正在加载数据...</TableCell>
                  </TableRow>
                ) : data.length === 0 ? (
                  <TableRow>
                    <TableCell colSpan={columns.length} className="h-32 text-center text-sm text-muted-foreground">{emptyText}</TableCell>
                  </TableRow>
                ) : (
                  data.map((row, rowIndex) => (
                    <TableRow key={getRowKey(row, rowIndex)}>
                      {columns.map((column) => {
                        const value = row[column.key as keyof T];
                        const content = column.render ? column.render(value, row, rowIndex) : getCellText(value);
                        const shouldEllipsis = column.ellipsis !== false;
                        const titleText = typeof content === "string" || typeof content === "number" ? String(content) : getCellText(value);
                        return (
                          <TableCell
                            key={String(column.key)}
                            className={cn("px-4 py-3 text-sm", alignClass(column.align), column.className)}
                            title={shouldEllipsis ? titleText : undefined}
                          >
                            {shouldEllipsis ? <div className="truncate">{content}</div> : content}
                          </TableCell>
                        );
                      })}
                    </TableRow>
                  ))
                )}
              </TableBody>
            </Table>
          </div>

          {pagination ? (
            <div className="flex flex-col gap-3 border-t border-border px-4 py-3 text-sm text-muted-foreground sm:flex-row sm:items-center sm:justify-between">
              <div className="flex items-center gap-2">
                <span>共 {pagination.total} 条</span>
                <span className="hidden sm:inline">/</span>
                <span>第 {currentPage} / {totalPages} 页</span>
              </div>
              <div className="flex flex-wrap items-center gap-2">
                <Select value={String(pageSize)} onValueChange={(value) => onSizeChange?.(Number(value))}>
                  <SelectTrigger className="h-9 w-[108px] bg-background">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {sizeOptions.map((size) => <SelectItem key={size} value={String(size)}>{size} 条/页</SelectItem>)}
                  </SelectContent>
                </Select>
                <Button type="button" variant="outline" size="icon" className="h-9 w-9" disabled={!hasPrev} onClick={() => onPageChange?.(1)}><ChevronsLeft className="h-4 w-4" /></Button>
                <Button type="button" variant="outline" size="icon" className="h-9 w-9" disabled={!hasPrev} onClick={() => onPageChange?.(currentPage - 1)}><ChevronLeft className="h-4 w-4" /></Button>
                <Button type="button" variant="outline" size="icon" className="h-9 w-9" disabled={!hasNext} onClick={() => onPageChange?.(currentPage + 1)}><ChevronRight className="h-4 w-4" /></Button>
                <Button type="button" variant="outline" size="icon" className="h-9 w-9" disabled={!hasNext} onClick={() => onPageChange?.(totalPages)}><ChevronsRight className="h-4 w-4" /></Button>
              </div>
            </div>
          ) : null}
        </div>
      ) : null}
    </section>
  );
}
