import type { ReactNode } from "react";
import "./table.css";

export interface Column<T> {
  /** Unique column key. */
  key: string;
  /** Header label. Omit for the status / actions rails. */
  header?: ReactNode;
  /** Cell renderer. */
  render: (row: T) => ReactNode;
  /** Extra class on the <td> (e.g. dt__status, dt__actions). */
  cellClass?: string;
}

interface TableProps<T> {
  columns: Column<T>[];
  rows: T[];
  rowKey: (row: T) => string;
  /** Optional per-row activation (opens detail). Bound to click, Enter, Space. */
  onRowClick?: (row: T) => void;
  /** Accessible label for the row's primary activation, e.g. the hostname. */
  rowLabel?: (row: T) => string;
  /** Cap the staggered fade-in so large lists don't crawl in. */
  maxStaggerRows?: number;
}

/**
 * Dense, console-style data table. Sticky header, hover highlight, hover-
 * revealed row actions, and a staggered fade-in on mount (capped so big lists
 * appear promptly). Column-driven so callers compose cells declaratively.
 */
export function Table<T>({
  columns,
  rows,
  rowKey,
  onRowClick,
  rowLabel,
  maxStaggerRows = 14,
}: TableProps<T>) {
  return (
    <div className="dt-wrap">
      <table className="dt">
        <thead>
          <tr>
            {columns.map((c) => (
              <th key={c.key} className={c.cellClass}>
                {c.header}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, i) => {
            const delay = i < maxStaggerRows ? `${i * 22}ms` : "0ms";
            return (
              <tr
                key={rowKey(row)}
                style={{
                  animationDelay: delay,
                  cursor: onRowClick ? "pointer" : undefined,
                }}
                onClick={onRowClick ? () => onRowClick(row) : undefined}
                tabIndex={onRowClick ? 0 : undefined}
                aria-label={
                  onRowClick && rowLabel
                    ? `Open detail for ${rowLabel(row)}`
                    : undefined
                }
                onKeyDown={
                  onRowClick
                    ? (e) => {
                        // Activate on Enter or Space, the standard for a
                        // button-like row. Space must not scroll the page.
                        if (e.key === "Enter" || e.key === " ") {
                          if (e.target !== e.currentTarget) return;
                          e.preventDefault();
                          onRowClick(row);
                        }
                      }
                    : undefined
                }
              >
                {columns.map((c) => (
                  <td key={c.key} className={c.cellClass}>
                    {c.render(row)}
                  </td>
                ))}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}
