import React, { useMemo } from 'react';
import './DataTable.css';

export interface Column<T> {
  key: keyof T | string;
  label: string;
  sortable?: boolean;
  render?: (item: T, index: number) => React.ReactNode;
  width?: string;
  align?: 'left' | 'center' | 'right';
}

export interface SortConfig {
  field: string;
  order: 'asc' | 'desc';
}

export interface DataTableProps<T> {
  data: T[];
  columns: Column<T>[];
  keyField?: keyof T;
  loading?: boolean;
  emptyMessage?: string;
  sortConfig?: SortConfig | null;
  onSort?: (field: string) => void;
  onRowClick?: (item: T, index: number) => void;
  selectable?: boolean;
  selectedIds?: Set<number | string>;
  onToggleSelect?: (id: number | string) => void;
  onToggleSelectAll?: () => void;
  isAllSelected?: boolean;
  isSomeSelected?: boolean;
  actions?: (item: T, index: number) => React.ReactNode;
  className?: string;
  striped?: boolean;
  hoverable?: boolean;
}

/**
 * Enhanced data table component with sorting, selection, and custom rendering
 * Works seamlessly with usePaginatedData, useQueryBuilder, and useBatchSelection hooks
 * 
 * @example
 * const { data, loading, setSort } = usePaginatedData('/articles');
 * const selection = useBatchSelection(data, 'id');
 * 
 * <DataTable
 *   data={data}
 *   columns={columns}
 *   loading={loading}
 *   onSort={setSort}
 *   selectable
 *   selectedIds={selection.selectedIds}
 *   onToggleSelect={selection.toggle}
 *   onToggleSelectAll={selection.toggleAll}
 * />
 */
export function DataTable<T extends Record<string, any>>({
  data,
  columns,
  keyField = 'id' as keyof T,
  loading = false,
  emptyMessage = 'No data available',
  sortConfig,
  onSort,
  onRowClick,
  selectable = false,
  selectedIds,
  onToggleSelect,
  onToggleSelectAll,
  isAllSelected = false,
  isSomeSelected = false,
  actions,
  className = '',
  striped = true,
  hoverable = true,
}: DataTableProps<T>) {
  const tableClasses = useMemo(() => {
    const classes = ['data-table'];
    if (striped) classes.push('data-table-striped');
    if (hoverable) classes.push('data-table-hoverable');
    if (loading) classes.push('data-table-loading');
    if (className) classes.push(className);
    return classes.join(' ');
  }, [striped, hoverable, loading, className]);

  const handleSort = (field: string, sortable?: boolean) => {
    if (sortable && onSort) {
      onSort(field);
    }
  };

  const getSortIcon = (field: string) => {
    if (!sortConfig || sortConfig.field !== field) {
      return '⇅';
    }
    return sortConfig.order === 'asc' ? '↑' : '↓';
  };

  if (loading) {
    return (
      <div className="data-table-container">
        <div className="data-table-loading-overlay">
          <div className="spinner"></div>
          <p>Loading...</p>
        </div>
      </div>
    );
  }

  if (data.length === 0) {
    return (
      <div className="data-table-container">
        <div className="data-table-empty">
          <p>{emptyMessage}</p>
        </div>
      </div>
    );
  }

  return (
    <div className="data-table-container">
      <table className={tableClasses}>
        <thead>
          <tr>
            {selectable && (
              <th className="data-table-select-col">
                <input
                  type="checkbox"
                  checked={isAllSelected}
                  ref={(input) => {
                    if (input) {
                      input.indeterminate = isSomeSelected;
                    }
                  }}
                  onChange={onToggleSelectAll}
                  aria-label="Select all rows"
                />
              </th>
            )}
            {columns.map((column) => (
              <th
                key={String(column.key)}
                className={`
                  ${column.sortable ? 'data-table-sortable' : ''}
                  data-table-align-${column.align || 'left'}
                `}
                style={{ width: column.width }}
                onClick={() => handleSort(String(column.key), column.sortable)}
              >
                <div className="data-table-header-content">
                  <span>{column.label}</span>
                  {column.sortable && (
                    <span className="data-table-sort-icon">
                      {getSortIcon(String(column.key))}
                    </span>
                  )}
                </div>
              </th>
            ))}
            {actions && <th className="data-table-actions-col">Actions</th>}
          </tr>
        </thead>
        <tbody>
          {data.map((item, index) => {
            const itemId = item[keyField];
            const isSelected = selectedIds?.has(itemId) || false;

            return (
              <tr
                key={String(itemId)}
                className={`
                  ${isSelected ? 'data-table-row-selected' : ''}
                  ${onRowClick ? 'data-table-row-clickable' : ''}
                `}
                onClick={() => onRowClick?.(item, index)}
              >
                {selectable && (
                  <td
                    className="data-table-select-col"
                    onClick={(e) => e.stopPropagation()}
                  >
                    <input
                      type="checkbox"
                      checked={isSelected}
                      onChange={() => onToggleSelect?.(itemId)}
                      aria-label={`Select row ${index + 1}`}
                    />
                  </td>
                )}
                {columns.map((column) => (
                  <td
                    key={String(column.key)}
                    className={`data-table-align-${column.align || 'left'}`}
                  >
                    {column.render
                      ? column.render(item, index)
                      : String(item[column.key] ?? '')}
                  </td>
                ))}
                {actions && (
                  <td
                    className="data-table-actions-col"
                    onClick={(e) => e.stopPropagation()}
                  >
                    {actions(item, index)}
                  </td>
                )}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}
