import type { ReactNode } from "react";
import { EmptyBlock, ErrorBlock } from "./StateBlock";

export interface Column<T> {
  key: string;
  header: ReactNode;
  render: (row: T) => ReactNode;
  /** Right-align (numeric) cells. */
  numeric?: boolean;
  /** Extra class on the td/th. */
  className?: string;
}

interface DataTableProps<T> {
  columns: Column<T>[];
  rows: T[];
  rowKey: (row: T) => string;
  loading?: boolean;
  error?: unknown;
  onRetry?: () => void;
  emptyTitle?: string;
  emptyHint?: string;
  caption?: string;
  /** Row click handler — renders rows as clickable. */
  onRowClick?: (row: T) => void;
  /** Number of skeleton rows while loading. */
  skeletonRows?: number;
}

/**
 * Data-dense table with unified loading / error / empty states.
 * Renders inside a horizontal-scroll wrapper so narrow viewports never
 * overflow the document.
 */
export function DataTable<T>({
  columns,
  rows,
  rowKey,
  loading = false,
  error,
  onRetry,
  emptyTitle = "No rows",
  emptyHint,
  caption,
  onRowClick,
  skeletonRows = 6,
}: DataTableProps<T>) {
  if (error !== undefined && error !== null) {
    return <ErrorBlock error={error} onRetry={onRetry} />;
  }

  if (loading) {
    return (
      <div role="status" aria-label="Loading table rows">
        {Array.from({ length: skeletonRows }, (_, i) => (
          <div className="skeleton-row" key={i} />
        ))}
      </div>
    );
  }

  if (rows.length === 0) {
    return <EmptyBlock title={emptyTitle} hint={emptyHint} />;
  }

  return (
    <div className="table-wrap">
      <table className="data-table">
        {caption ? <caption className="sr-only">{caption}</caption> : null}
        <thead>
          <tr>
            {columns.map((col) => (
              <th
                key={col.key}
                scope="col"
                className={`${col.numeric ? "num" : ""} ${col.className ?? ""}`.trim()}
              >
                {col.header}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row) => (
            <tr
              key={rowKey(row)}
              className={onRowClick ? "clickable" : undefined}
              onClick={onRowClick ? () => onRowClick(row) : undefined}
              // Clickable rows behave like links: focusable and Enter/Space-activated.
              tabIndex={onRowClick ? 0 : undefined}
              role={onRowClick ? "link" : undefined}
              onKeyDown={
                onRowClick
                  ? (event) => {
                      if (event.key === "Enter" || event.key === " ") {
                        event.preventDefault();
                        onRowClick(row);
                      }
                    }
                  : undefined
              }
            >
              {columns.map((col) => (
                <td
                  key={col.key}
                  className={`${col.numeric ? "num" : ""} ${col.className ?? ""}`.trim()}
                >
                  {col.render(row)}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
