import type { CSSProperties } from "react";

import { getT } from "@/lib/content";
import type { Locale } from "@/lib/locales";
import type { BlueprintSheet as Sheet } from "@/lib/schemas";

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

/**
 * The module's own document, as a structure rather than a screenshot.
 *
 * Nothing here imitates the product's chrome. It is the module's real document
 * structure — Sulsys's own column names, document names and function keys —
 * with demonstration data the caption names as such.
 *
 * Two variants. `frame` is V3's: the record on a desk-grey mat, a figure in a
 * page. `world` is V4's: the same record set at full width as the first
 * chapter of a product page, unframed, in the document voice, with the tempo
 * of the product it belongs to —
 *
 *   ledger   rows post one by one; the double rule draws under the total
 *   pos      rows post, and the quantities cut up into their cells last
 *   table    everything is there; the period's closing rule draws
 *   tables   the places change state one after another, then the order ticks in
 *
 * `tone="navy"` paints the world on the system's surface. Only Caffe uses it:
 * the one product that runs at night, on a touch screen, in a room.
 */
export function BlueprintSheet({
  sheet,
  locale,
  variant = "frame",
  tone = "paper",
}: {
  sheet: Sheet;
  locale: Locale;
  variant?: "frame" | "world";
  tone?: "paper" | "navy";
}) {
  const t = getT(locale);
  const world = variant === "world";
  const stateLabel = {
    free: t("sheet.tableFree"),
    open: t("sheet.tableOpen"),
    bill: t("sheet.tableBill"),
  } as const;

  const columnLabel = (index: number) => sheet.columns[index] ?? "";

  /*
   * Right-align a column only when it actually holds figures. A sheet like the
   * hospitality order ticket has "Banak" and "14:12" in its trailing columns,
   * and right-aligning those would read as a mistake rather than as a ledger.
   */
  const numericColumn = sheet.columns.map((_, index) => {
    if (index === 0) return false;
    const cells = sheet.rows.map((row) => row[index] ?? "").filter((cell) => cell.length > 0);
    if (cells.length === 0) return false;
    return cells.every(
      (cell) => /^[\d.,\s]+(\s?(m²|m|kg|km|%))?$/u.test(cell.trim()) || cell.trim() === "—",
    );
  });

  const cellClass = (index: number) => (numericColumn[index] ? styles.num : undefined);
  const at = (i: number) => ({ "--i": i }) as CSSProperties;

  return (
    <figure
      className={world ? styles.world : styles.frame}
      data-kind={sheet.kind}
      data-tone={world ? tone : undefined}
    >
      <div className={styles.sheet}>
        <div className={styles.head}>
          <span className={styles.title}>{sheet.title}</span>
          <span className={styles.badge}>{world ? t("panel.sample") : t("sheet.badge")}</span>
        </div>

        <div className={styles.body}>
          {sheet.cells && sheet.cells.length > 0 ? (
            <div className={styles.mapWrap}>
              <p className={styles.mapLabel}>{t("sheet.tables")}</p>
              <ul className={styles.map}>
                {sheet.cells.map((cell, index) => (
                  <li
                    key={cell.label}
                    className={[
                      styles.cell,
                      cell.state === "open" ? styles.open : null,
                      cell.state === "bill" ? styles.bill : null,
                    ]
                      .filter(Boolean)
                      .join(" ")}
                    style={at(index)}
                  >
                    <span className={styles.cellNumber}>{cell.label}</span>
                    <span className={styles.cellState}>{stateLabel[cell.state]}</span>
                  </li>
                ))}
              </ul>
            </div>
          ) : null}

          {sheet.cells && sheet.cells.length > 0 ? (
            <p className={styles.mapLabel}>{t("sheet.order")}</p>
          ) : null}

          <table className={styles.table} data-kind={sheet.kind}>
            <caption className="visually-hidden">{sheet.caption}</caption>
            <thead>
              <tr>
                {sheet.columns.map((column, index) => (
                  <th key={column} scope="col" className={cellClass(index)}>
                    {column}
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {sheet.rows.map((row, rowIndex) => (
                <tr key={`${sheet.title}-${rowIndex}`} style={at(rowIndex)}>
                  {row.map((cell, index) => (
                    <td key={index} className={cellClass(index)} data-label={columnLabel(index)}>
                      {numericColumn[index] ? <span className={styles.figure}>{cell}</span> : cell}
                    </td>
                  ))}
                </tr>
              ))}
              {sheet.total ? (
                <tr className={styles.totalRow} style={at(sheet.rows.length)}>
                  {sheet.total.map((cell, index) => (
                    <td key={index} className={cellClass(index)} data-label={columnLabel(index)}>
                      {cell}
                    </td>
                  ))}
                </tr>
              ) : null}
            </tbody>
          </table>

          {world ? <div className={styles.foot} aria-hidden="true" /> : null}

          {sheet.keys && sheet.keys.length > 0 ? (
            <div className={styles.keys}>
              <span className="visually-hidden">{t("sheet.keys")}</span>
              {sheet.keys.map((key) => (
                <span key={key.key} className={styles.key}>
                  <span className={styles.keyCode}>{key.key}</span>
                  <span className={styles.keyLabel}>{key.label}</span>
                </span>
              ))}
            </div>
          ) : null}
        </div>
      </div>

      <figcaption className={styles.caption}>
        <span>{sheet.caption}</span>
        <span className={styles.note}>{t("sheet.note")}</span>
      </figcaption>
    </figure>
  );
}
