import * as React from 'react';
import { useState, useEffect, useRef, useCallback, useImperativeHandle } from 'react';
import { Loader2, Search, RotateCcw } from 'lucide-react';
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from './table';
import { DataTablePagination } from './pagination';
import { Button } from './button';
import { Input } from './input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './select';
import type { Page } from '@/types/base';
import { DEFAULT_PAGE_SIZE, DEFAULT_PAGE_NUM } from '@/utils/page';

// 列定义
export interface ColumnDef<T> {
  key: string;
  title: React.ReactNode;
  width?: string;
  sticky?: boolean;
  render?: (value: any, record: T, index: number) => React.ReactNode;
  dataIndex?: string;
  className?: string;
}

// 搜索字段定义
export interface SearchFieldDef {
  key: string;
  type: 'input' | 'select';
  placeholder?: string;
  options?: { label: string; value: string | number }[];
  width?: string;
  /** 是否支持回车搜索（仅 input 类型） */
  enterSearch?: boolean;
}

// 查询参数基础类型
export interface BaseQuery {
  pageNum?: number;
  pageSize?: number;
  [key: string]: any;
}

// 组件 Props
export interface PaginatedTableProps<T, Q extends BaseQuery = BaseQuery> {
  fetchFn: (query: Q) => Promise<Page<T>>;
  columns: ColumnDef<T>[];
  /** 搜索字段定义（简化模式） */
  searchFields?: SearchFieldDef[];
  /** 自定义搜索栏（完全自定义模式） */
  searchBar?: React.ReactNode;
  /** 工具栏（新建按钮等） */
  toolbar?: React.ReactNode;
  /** 初始查询参数 */
  initialQuery?: Omit<Q, 'pageNum' | 'pageSize'>;
  rowKey?: keyof T | ((record: T) => string | number);
  minWidth?: string;
  pageSize?: number;
  emptyText?: React.ReactNode;
  loadingText?: React.ReactNode;
  /** 搜索栏和表格之间的间距 */
  searchGap?: string;
}

// 暴露给外部的方法
export interface PaginatedTableRef<T> {
  refresh: (showLoading?: boolean) => Promise<void>;
  reset: () => void;
  search: () => void;
  getData: () => Page<T> | null;
  getQuery: () => Record<string, any>;
  updateRecord: (id: string | number, updates: Partial<T>) => void;
}

function getNestedValue(obj: any, path?: string): any {
  if (!path) return undefined;
  return path.split('.').reduce((acc, part) => acc?.[part], obj);
}

function getRowKey<T>(record: T, rowKey: keyof T | ((record: T) => string | number) | undefined, index: number): string | number {
  if (!rowKey) return index;
  if (typeof rowKey === 'function') return rowKey(record);
  return record[rowKey] as string | number;
}

function PaginatedTableInner<T extends Record<string, any>, Q extends BaseQuery = BaseQuery>(
  props: PaginatedTableProps<T, Q>,
  ref: React.ForwardedRef<PaginatedTableRef<T>>
) {
  const {
    fetchFn,
    columns,
    searchFields,
    searchBar,
    toolbar,
    initialQuery = {} as Omit<Q, 'pageNum' | 'pageSize'>,
    rowKey,
    minWidth,
    pageSize: initialPageSize = DEFAULT_PAGE_SIZE,
    emptyText = '暂无数据',
    loadingText = '加载中...',
    searchGap = 'mb-4',
  } = props;

  const [data, setData] = useState<Page<T> | null>(null);
  const [loading, setLoading] = useState(true); // 首次加载显示 loading
  const [pageNum, setPageNum] = useState(DEFAULT_PAGE_NUM);
  const [pageSize] = useState(initialPageSize);
  const [searchValues, setSearchValues] = useState<Record<string, any>>(initialQuery);

  const isFirstLoad = useRef(true);

  // 加载数据（不再控制 loading 状态，只有首次加载显示）
  const loadData = useCallback(async () => {
    try {
      const result = await fetchFn({
        ...searchValues,
        pageNum,
        pageSize,
      } as Q);
      setData(result);
    } catch (error) {
      console.error('PaginatedTable 加载数据失败:', error);
    } finally {
      if (isFirstLoad.current) {
        setLoading(false);
        isFirstLoad.current = false;
      }
    }
  }, [fetchFn, searchValues, pageNum, pageSize]);

  // 监听分页变化
  useEffect(() => {
    loadData();
  }, [pageNum, pageSize]);

  // 搜索
  const handleSearch = useCallback(() => {
    if (pageNum === DEFAULT_PAGE_NUM) {
      loadData();
    } else {
      setPageNum(DEFAULT_PAGE_NUM);
    }
  }, [pageNum, loadData]);

  // 重置
  const handleReset = useCallback(() => {
    setSearchValues(initialQuery);
    setPageNum(DEFAULT_PAGE_NUM);
  }, [initialQuery]);

  // 分页切换
  const handlePageChange = useCallback((newPageNum: number) => {
    setPageNum(newPageNum);
  }, []);

  // 暴露方法
  useImperativeHandle(ref, () => ({
    refresh: async () => {
      await loadData();
    },
    reset: handleReset,
    search: handleSearch,
    getData: () => data,
    getQuery: () => searchValues,
    updateRecord: (id, updates) => {
      setData(prev => {
        if (!prev) return prev;
        return {
          ...prev,
          content: prev.content.map(item =>
            getRowKey(item, rowKey, -1) === id ? { ...item, ...updates } : item
          ),
        };
      });
    },
  }), [data, loadData, handleReset, handleSearch, searchValues, rowKey]);

  // 渲染搜索字段
  const renderSearchField = (field: SearchFieldDef) => {
    const value = searchValues[field.key];
    
    if (field.type === 'input') {
      return (
        <div key={field.key} className={field.width || 'flex-1 max-w-md'}>
          <Input
            placeholder={field.placeholder}
            value={value || ''}
            onChange={(e) => setSearchValues(prev => ({ ...prev, [field.key]: e.target.value }))}
            onKeyDown={(e) => field.enterSearch !== false && e.key === 'Enter' && handleSearch()}
          />
        </div>
      );
    }
    
    if (field.type === 'select') {
      return (
        <Select
          key={field.key}
          value={value?.toString() || 'all'}
          onValueChange={(v) => setSearchValues(prev => ({ ...prev, [field.key]: v !== 'all' ? v : undefined }))}
        >
          <SelectTrigger className={field.width || 'w-[180px]'}>
            <SelectValue placeholder={field.placeholder} />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">{field.placeholder || '全部'}</SelectItem>
            {field.options?.map(opt => (
              <SelectItem key={opt.value} value={opt.value.toString()}>{opt.label}</SelectItem>
            ))}
          </SelectContent>
        </Select>
      );
    }
    
    return null;
  };

  // 渲染单元格
  const renderCell = (column: ColumnDef<T>, record: T, index: number) => {
    if (column.render) {
      const value = column.dataIndex ? getNestedValue(record, column.dataIndex) : undefined;
      return column.render(value, record, index);
    }
    if (column.dataIndex) {
      return getNestedValue(record, column.dataIndex);
    }
    return null;
  };

  const pageCount = data?.totalPages || 0;
  const hasData = data && data.content && data.content.length > 0;
  const showSearchBar = searchFields && searchFields.length > 0;

  return (
    <div className="space-y-0">
      {/* 搜索栏 */}
      {(showSearchBar || searchBar || toolbar) && (
        <div className={`flex flex-wrap items-center gap-4 ${searchGap}`}>
          {searchBar || (
            <>
              {searchFields?.map(renderSearchField)}
              <Button type="button" onClick={handleSearch}>
                <Search className="h-4 w-4 mr-2" />查询
              </Button>
              <Button type="button" variant="outline" onClick={handleReset}>
                <RotateCcw className="h-4 w-4 mr-2" />重置
              </Button>
            </>
          )}
          {toolbar && <div className="ml-auto flex items-center gap-2">{toolbar}</div>}
        </div>
      )}

      {/* 表格 */}
      <div className="rounded-md border">
        <Table minWidth={minWidth}>
          <TableHeader>
            <TableRow>
              {columns.map(col => (
                <TableHead key={col.key} width={col.width} sticky={col.sticky}>
                  {col.title}
                </TableHead>
              ))}
            </TableRow>
          </TableHeader>
          <TableBody>
            {loading ? (
              <TableRow>
                <TableCell colSpan={columns.length} className="h-24 text-center">
                  <div className="flex items-center justify-center gap-2">
                    <Loader2 className="h-4 w-4 animate-spin" />
                    <span className="text-muted-foreground">{loadingText}</span>
                  </div>
                </TableCell>
              </TableRow>
            ) : hasData ? (
              data.content.map((record, index) => (
                <TableRow key={getRowKey(record, rowKey, index)}>
                  {columns.map(col => (
                    <TableCell key={col.key} width={col.width} sticky={col.sticky} className={col.className}>
                      {renderCell(col, record, index)}
                    </TableCell>
                  ))}
                </TableRow>
              ))
            ) : (
              <TableRow>
                <TableCell colSpan={columns.length} className="h-24 text-center">
                  <span className="text-muted-foreground">{emptyText}</span>
                </TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>
      </div>
      
      {/* 分页 */}
      {pageCount > 0 && (
        <DataTablePagination
          pageIndex={pageNum}
          pageSize={pageSize}
          pageCount={pageCount}
          onPageChange={handlePageChange}
        />
      )}
    </div>
  );
}

export const PaginatedTable = React.forwardRef(PaginatedTableInner) as <
  T extends Record<string, any>,
  Q extends BaseQuery = BaseQuery
>(
  props: PaginatedTableProps<T, Q> & { ref?: React.ForwardedRef<PaginatedTableRef<T>> }
) => React.ReactElement;

export default PaginatedTable;
