import { ReactNode } from 'react'
import clsx from 'clsx'

interface Column<T> {
  header: string
  accessor: (row: T) => ReactNode
  className?: string
}

interface TableProps<T> {
  columns: Column<T>[]
  data: T[]
  className?: string
  emptyMessage?: string
  /**
   * responsive: stacked cards below `md`, table at md+.
   * tabular: always use columnar HTML table (holder lists, dense numeric tables).
   */
  layout?: 'responsive' | 'tabular'
  /** Stable key for each row (e.g. row => row.id or row => row.hash). Falls back to index if not provided. */
  keyExtractor?: (row: T) => string | number
}

export function Table<T>({
  columns,
  data,
  className,
  emptyMessage = 'No data available right now.',
  layout = 'responsive',
  keyExtractor,
}: TableProps<T>) {
  if (data.length === 0) {
    return (
      <div
        className={clsx(
          'rounded-xl border border-dashed border-gray-300 bg-white px-4 py-6 text-sm text-gray-600 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-400',
          className,
        )}
      >
        {emptyMessage}
      </div>
    )
  }

  const stackedClass = layout === 'tabular' ? 'hidden' : 'grid gap-3 md:hidden'
  const tableWrapperClass = layout === 'tabular' ? 'overflow-x-auto' : 'hidden overflow-x-auto md:block'

  return (
    <div className={clsx('space-y-3', className)}>
      <div className={stackedClass}>
        {data.map((row, rowIndex) => (
          <div
            key={keyExtractor ? keyExtractor(row) : rowIndex}
            className="rounded-xl border border-gray-200 bg-white p-4 shadow-sm dark:border-gray-700 dark:bg-gray-900"
          >
            <dl className="space-y-3">
              {columns.map((column, colIndex) => (
                <div key={colIndex} className="space-y-1">
                  <dt className="text-[11px] font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400">
                    {column.header}
                  </dt>
                  <dd className={clsx('min-w-0 text-sm text-gray-900 dark:text-gray-100', column.className)}>
                    {column.accessor(row)}
                  </dd>
                </div>
              ))}
            </dl>
          </div>
        ))}
      </div>

      <div className={tableWrapperClass}>
        <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
          <thead className="bg-gray-50 dark:bg-gray-800">
            <tr>
              {columns.map((column, index) => (
                <th
                  key={index}
                  className={clsx(
                    'px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-gray-500 dark:text-gray-400 lg:px-6',
                    column.className
                  )}
                >
                  {column.header}
                </th>
              ))}
            </tr>
          </thead>
          <tbody className="divide-y divide-gray-200 bg-white dark:divide-gray-700 dark:bg-gray-900">
            {data.map((row, rowIndex) => (
              <tr key={keyExtractor ? keyExtractor(row) : rowIndex} className="hover:bg-gray-50 dark:hover:bg-gray-800">
                {columns.map((column, colIndex) => (
                  <td
                    key={colIndex}
                    className={clsx(
                      'px-4 py-4 align-top text-sm text-gray-900 dark:text-gray-100 lg:px-6',
                      column.className
                    )}
                  >
                    {column.accessor(row)}
                  </td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  )
}
