import React from 'react';
import { clsx } from 'clsx';

export interface TableProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
}

/**
 * Table container using divs for better responsiveness and control
 */
export const Table = React.forwardRef<HTMLDivElement, TableProps>(
  ({ className, children, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={clsx('w-full border rounded-lg overflow-hidden', 'bg-background', className)}
        role="table"
        {...props}
      >
        {children}
      </div>
    );
  }
);
Table.displayName = 'Table';

export interface TableHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
}

/**
 * Table header container
 */
export const TableHeader = React.forwardRef<HTMLDivElement, TableHeaderProps>(
  ({ className, children, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={clsx(
          'bg-muted/50 border-b',
          'grid gap-4 px-4 py-3',
          'text-xs font-medium text-muted-foreground uppercase tracking-wider',
          className
        )}
        role="rowgroup"
        {...props}
      >
        {children}
      </div>
    );
  }
);
TableHeader.displayName = 'TableHeader';

export interface TableRowProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
  selected?: boolean;
  interactive?: boolean;
}

/**
 * Table row using div
 */
export const TableRow = React.forwardRef<HTMLDivElement, TableRowProps>(
  ({ className, children, selected, interactive = false, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={clsx(
          'grid gap-4 px-4 py-3 border-b border-border last:border-b-0',
          'bg-background',
          'transition-colors',
          {
            'bg-primary/5 border-primary/20': selected,
            'hover:bg-muted/50 cursor-pointer': interactive && !selected,
            'hover:bg-primary/10': interactive && selected,
          },
          className
        )}
        role="row"
        {...props}
      >
        {children}
      </div>
    );
  }
);
TableRow.displayName = 'TableRow';

export interface TableHeadProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
  sortable?: boolean;
  sorted?: 'asc' | 'desc' | null;
  onSort?: () => void;
  width?: string | number;
  minWidth?: string | number;
}

/**
 * Table header cell
 */
export const TableHead = React.forwardRef<HTMLDivElement, TableHeadProps>(
  (
    { className, children, sortable = false, sorted = null, onSort, width, minWidth, ...props },
    ref
  ) => {
    const style: React.CSSProperties = {};
    if (width) style.width = typeof width === 'number' ? `${width}px` : width;
    if (minWidth) style.minWidth = typeof minWidth === 'number' ? `${minWidth}px` : minWidth;

    return (
      <div
        ref={ref}
        className={clsx(
          'flex items-center gap-2',
          {
            'cursor-pointer select-none hover:text-foreground': sortable,
          },
          className
        )}
        style={style}
        role="columnheader"
        onClick={sortable ? onSort : undefined}
        {...props}
      >
        {children}
        {sortable && (
          <span className="text-muted-foreground/50">
            {sorted === 'asc' ? '↑' : sorted === 'desc' ? '↓' : '⇅'}
          </span>
        )}
      </div>
    );
  }
);
TableHead.displayName = 'TableHead';

export interface TableCellProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
  width?: string | number;
  minWidth?: string | number;
  align?: 'left' | 'center' | 'right';
}

/**
 * Table cell
 */
export const TableCell = React.forwardRef<HTMLDivElement, TableCellProps>(
  ({ className, children, width, minWidth, align = 'left', ...props }, ref) => {
    const style: React.CSSProperties = {};
    if (width) style.width = typeof width === 'number' ? `${width}px` : width;
    if (minWidth) style.minWidth = typeof minWidth === 'number' ? `${minWidth}px` : minWidth;

    return (
      <div
        ref={ref}
        className={clsx(
          'flex items-center',
          {
            'justify-start': align === 'left',
            'justify-center': align === 'center',
            'justify-end': align === 'right',
          },
          className
        )}
        style={style}
        role="cell"
        {...props}
      >
        {children}
      </div>
    );
  }
);
TableCell.displayName = 'TableCell';

export interface TableBodyProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
}

/**
 * Table body container
 */
export const TableBody = React.forwardRef<HTMLDivElement, TableBodyProps>(
  ({ className, children, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={clsx('divide-y divide-border', className)}
        role="rowgroup"
        {...props}
      >
        {children}
      </div>
    );
  }
);
TableBody.displayName = 'TableBody';

export interface TableEmptyProps extends React.HTMLAttributes<HTMLDivElement> {
  message?: string;
  description?: string;
  action?: React.ReactNode;
}

/**
 * Empty state for table
 */
export const TableEmpty = React.forwardRef<HTMLDivElement, TableEmptyProps>(
  ({ className, message = 'No data available', description, action, ...props }, ref) => {
    return (
      <div
        ref={ref}
        className={clsx(
          'flex flex-col items-center justify-center py-12 px-4 text-center',
          className
        )}
        {...props}
      >
        <p className="text-sm font-medium text-foreground mb-1">{message}</p>
        {description && <p className="text-sm text-muted-foreground mb-4">{description}</p>}
        {action && <div className="mt-2">{action}</div>}
      </div>
    );
  }
);
TableEmpty.displayName = 'TableEmpty';

/**
 * Responsive table wrapper that switches to card view on mobile
 */
export interface ResponsiveTableProps<T> {
  data: T[];
  columns: Array<{
    key: string;
    header: string;
    render: (item: T, index: number) => React.ReactNode;
    width?: string | number;
    minWidth?: string | number;
    sortable?: boolean;
    align?: 'left' | 'center' | 'right';
  }>;
  onSort?: (key: string, direction: 'asc' | 'desc') => void;
  sortedColumn?: string | null;
  sortDirection?: 'asc' | 'desc' | null;
  emptyMessage?: string;
  emptyDescription?: string;
  emptyAction?: React.ReactNode;
  selectedRows?: Set<string>;
  onRowSelect?: (id: string) => void;
  getRowId?: (item: T) => string;
  renderMobileCard?: (item: T, index: number) => React.ReactNode;
  isLoading?: boolean;
  loadingRows?: number;
  className?: string;
}

export function ResponsiveTable<T>({
  data,
  columns,
  onSort,
  sortedColumn = null,
  sortDirection = null,
  emptyMessage = 'No data available',
  emptyDescription,
  emptyAction,
  selectedRows,
  onRowSelect,
  getRowId,
  renderMobileCard,
  isLoading = false,
  loadingRows = 5,
  className,
}: ResponsiveTableProps<T>) {
  const handleSort = (key: string) => {
    if (!onSort) return;
    const newDirection = sortedColumn === key && sortDirection === 'asc' ? 'desc' : 'asc';
    onSort(key, newDirection);
  };

  const gridTemplateColumns = columns
    .map((col) => {
      if (col.width) {
        return typeof col.width === 'number' ? `${col.width}px` : col.width;
      }
      return '1fr';
    })
    .join(' ');

  if (isLoading) {
    // Loading skeleton
    return (
      <Table className={className}>
        <TableHeader style={{ gridTemplateColumns }} className="grid">
          {columns.map((column) => (
            <TableHead key={column.key} width={column.width} minWidth={column.minWidth}>
              <div className="h-4 w-20 bg-muted animate-pulse rounded" />
            </TableHead>
          ))}
        </TableHeader>
        <TableBody>
          {Array.from({ length: loadingRows }).map((_, index) => (
            <TableRow key={`loading-${index}`} style={{ gridTemplateColumns }} className="grid">
              {columns.map((column) => (
                <TableCell key={column.key}>
                  <div className="h-4 w-full bg-muted animate-pulse rounded" />
                </TableCell>
              ))}
            </TableRow>
          ))}
        </TableBody>
      </Table>
    );
  }

  if (data.length === 0) {
    return (
      <Table className={className}>
        <TableEmpty message={emptyMessage} description={emptyDescription} action={emptyAction} />
      </Table>
    );
  }

  return (
    <>
      {/* Desktop Table View */}
      <div className="hidden md:block">
        <Table className={className}>
          <TableHeader style={{ gridTemplateColumns }} className="grid">
            {columns.map((column) => (
              <TableHead
                key={column.key}
                sortable={column.sortable}
                sorted={sortedColumn === column.key ? sortDirection : null}
                onSort={column.sortable ? () => handleSort(column.key) : undefined}
                width={column.width}
                minWidth={column.minWidth}
                align={column.align}
              >
                {column.header}
              </TableHead>
            ))}
          </TableHeader>
          <TableBody>
            {data.map((item, index) => {
              const rowId = getRowId ? getRowId(item) : String(index);
              const isSelected = selectedRows?.has(rowId) ?? false;

              return (
                <TableRow
                  key={rowId}
                  selected={isSelected}
                  interactive={!!onRowSelect}
                  onClick={onRowSelect ? () => onRowSelect(rowId) : undefined}
                  style={{ gridTemplateColumns }}
                  className="grid"
                >
                  {columns.map((column) => (
                    <TableCell
                      key={column.key}
                      width={column.width}
                      minWidth={column.minWidth}
                      align={column.align}
                    >
                      {column.render(item, index)}
                    </TableCell>
                  ))}
                </TableRow>
              );
            })}
          </TableBody>
        </Table>
      </div>

      {/* Mobile Card View */}
      <div className="md:hidden space-y-4">
        {data.map((item, index) => {
          if (renderMobileCard) {
            return (
              <React.Fragment key={getRowId ? getRowId(item) : index}>
                {renderMobileCard(item, index)}
              </React.Fragment>
            );
          }

          // Default mobile card rendering
          return (
            <div
              key={getRowId ? getRowId(item) : index}
              className="border rounded-lg p-4 space-y-3 bg-card"
            >
              {columns.map((column) => (
                <div key={column.key} className="flex flex-col">
                  <span className="text-xs font-medium text-muted-foreground mb-1">
                    {column.header}
                  </span>
                  <div className="text-sm text-foreground">{column.render(item, index)}</div>
                </div>
              ))}
            </div>
          );
        })}
      </div>
    </>
  );
}
