'use client';

import { ReactNode } from 'react';
import { cn } from '@/utils/helpers';
import { Loading } from '../Loading';
import styles from './Table.module.scss';

export interface TableColumn<T> {
  key: string;
  title: string;
  width?: number | string;
  sortable?: boolean;
  align?: 'left' | 'center' | 'right';
  render?: (value: unknown, record: T, index: number) => ReactNode;
}

export interface TableProps<T> {
  columns: TableColumn<T>[];
  data: T[];
  loading?: boolean;
  rowKey?: string | ((record: T) => string);
  rowSelection?: {
    selectedRowKeys: string[];
    onChange: (keys: string[]) => void;
  };
  onRowClick?: (record: T) => void;
  emptyText?: string;
  className?: string;
}

export function Table<T extends object>({
  columns,
  data,
  loading = false,
  rowKey = 'id',
  rowSelection,
  onRowClick,
  emptyText = '暂无数据',
  className,
}: TableProps<T>) {
  const getRowKey = (record: T, index: number): string => {
    if (typeof rowKey === 'function') {
      return rowKey(record);
    }
    return String((record as Record<string, unknown>)[rowKey] ?? index);
  };

  const handleSelectAll = (checked: boolean) => {
    if (!rowSelection) return;
    if (checked) {
      rowSelection.onChange(data.map((record, index) => getRowKey(record, index)));
    } else {
      rowSelection.onChange([]);
    }
  };

  const handleSelectRow = (key: string, checked: boolean) => {
    if (!rowSelection) return;
    if (checked) {
      rowSelection.onChange([...rowSelection.selectedRowKeys, key]);
    } else {
      rowSelection.onChange(rowSelection.selectedRowKeys.filter((k) => k !== key));
    }
  };

  const isAllSelected = data.length > 0 && rowSelection?.selectedRowKeys.length === data.length;
  const isIndeterminate =
    rowSelection &&
    rowSelection.selectedRowKeys.length > 0 &&
    rowSelection.selectedRowKeys.length < data.length;

  return (
    <div className={cn(styles.tableWrapper, className)}>
      <table className={styles.table}>
        <thead className={styles.table__head}>
          <tr>
            {rowSelection && (
              <th className={styles.table__th} style={{ width: 48 }}>
                <input
                  type="checkbox"
                  checked={isAllSelected}
                  ref={(el) => {
                    if (el) el.indeterminate = isIndeterminate ?? false;
                  }}
                  onChange={(e) => handleSelectAll(e.target.checked)}
                  className={styles.table__checkbox}
                />
              </th>
            )}
            {columns.map((column) => (
              <th
                key={column.key}
                className={cn(styles.table__th, styles[`table__th--${column.align || 'left'}`])}
                style={{ width: column.width }}
              >
                {column.title}
              </th>
            ))}
          </tr>
        </thead>
        <tbody className={styles.table__body}>
          {loading ? (
            <tr>
              <td
                colSpan={columns.length + (rowSelection ? 1 : 0)}
                className={styles.table__loading}
              >
                <Loading size="md" />
              </td>
            </tr>
          ) : data.length === 0 ? (
            <tr>
              <td colSpan={columns.length + (rowSelection ? 1 : 0)} className={styles.table__empty}>
                {emptyText}
              </td>
            </tr>
          ) : (
            data.map((record, index) => {
              const key = getRowKey(record, index);
              const isSelected = rowSelection?.selectedRowKeys.includes(key);

              return (
                <tr
                  key={key}
                  className={cn(
                    styles.table__tr,
                    isSelected && styles['table__tr--selected'],
                    onRowClick && styles['table__tr--clickable']
                  )}
                  onClick={() => onRowClick?.(record)}
                >
                  {rowSelection && (
                    <td className={styles.table__td}>
                      <input
                        type="checkbox"
                        checked={isSelected}
                        onChange={(e) => {
                          e.stopPropagation();
                          handleSelectRow(key, e.target.checked);
                        }}
                        onClick={(e) => e.stopPropagation()}
                        className={styles.table__checkbox}
                      />
                    </td>
                  )}
                  {columns.map((column) => (
                    <td
                      key={column.key}
                      className={cn(
                        styles.table__td,
                        styles[`table__td--${column.align || 'left'}`]
                      )}
                    >
                      {column.render
                        ? column.render((record as Record<string, unknown>)[column.key], record, index)
                        : ((record as Record<string, unknown>)[column.key] as ReactNode)}
                    </td>
                  ))}
                </tr>
              );
            })
          )}
        </tbody>
      </table>
    </div>
  );
}
