import type { ReactNode } from "react";

import styles from "./RecordTable.module.css";

export type Column = {
  key: string;
  label: string;
  /** Right-aligned tabular figures. */
  numeric?: boolean;
  /** Mono, narrow — for codes like 01 or F12. */
  code?: boolean;
  /** Carries the row's subject; set in 500 weight. */
  subject?: boolean;
};

export type Row = {
  id: string;
  cells: ReactNode[];
};

/**
 * One table for every ruled list on the site. A `total` row, when given, is
 * set off by a heavier rule with its value in green — the "posted" line.
 */
export function RecordTable({
  columns,
  rows,
  total,
  caption,
  surface = "paper",
}: {
  columns: Column[];
  rows: Row[];
  total?: ReactNode[];
  /** Accessible description; visually hidden. */
  caption?: string;
  surface?: "paper" | "ink";
}) {
  const cellClass = (column: Column) =>
    [
      column.numeric ? styles.num : null,
      column.code ? styles.code : null,
      column.subject ? styles.doc : null,
    ]
      .filter(Boolean)
      .join(" ") || undefined;

  return (
    <div className={[styles.wrap, surface === "ink" ? styles.ink : null].filter(Boolean).join(" ")}>
      <table className={styles.table} data-columns={columns.length}>
        {caption ? <caption className="visually-hidden">{caption}</caption> : null}
        <thead>
          <tr>
            {columns.map((column) => (
              <th key={column.key} scope="col" className={cellClass(column)}>
                {column.label}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row) => (
            <tr key={row.id}>
              {row.cells.map((cell, index) => {
                const column = columns[index];
                return (
                  <td
                    key={column?.key ?? index}
                    className={column ? cellClass(column) : undefined}
                    data-label={column?.label}
                  >
                    {cell}
                  </td>
                );
              })}
            </tr>
          ))}
          {total ? (
            <tr className={styles.total}>
              {total.map((cell, index) => {
                const column = columns[index];
                return (
                  <td
                    key={column?.key ?? index}
                    className={column ? cellClass(column) : undefined}
                    data-label={column?.label}
                  >
                    {cell}
                  </td>
                );
              })}
            </tr>
          ) : null}
        </tbody>
      </table>
    </div>
  );
}
