"use client";

import { useRef } from "react";
import { Controller, useWatch } from "react-hook-form";
import { Input } from "@/components/ui/input";
import { Table, TableBody, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { cn } from "@/lib/utils";
import { formatNumber } from "@/app/lib/format";

/** Form key of one colour x size cell. */
export const matrixCellKey = (rowId, columnId) => `c${rowId}s${columnId}`;

const toNumber = (value) => {
  const number = Number(value);
  return Number.isFinite(number) && number > 0 ? number : 0;
};

/** Row, column, and grand totals of a { [matrixCellKey]: "12" } object. */
export function sumMatrix(values, rows, columns) {
  const rowTotals = {};
  const columnTotals = {};
  let total = 0;
  rows.forEach((row) => {
    columns.forEach((column) => {
      const quantity = toNumber(values?.[matrixCellKey(row.id, column.id)]);
      rowTotals[row.id] = (rowTotals[row.id] || 0) + quantity;
      columnTotals[column.id] = (columnTotals[column.id] || 0) + quantity;
      total += quantity;
    });
  });
  return { rowTotals, columnTotals, total: Math.round(total * 1000) / 1000 };
}

/**
 * Editable colour (rows) x size (columns) quantity grid with row, column, and grand totals.
 * Values live in React Hook Form under `name` as { [matrixCellKey(rowId, columnId)]: "quantity" }.
 * Keyboard: Tab moves across a row, Enter / Arrow down moves down a column, Arrow up moves up.
 */
export function QuantityMatrix({ control, name = "cells", rows, columns, readOnly = false, rowLabel = "Colour", unit = "pcs", caption, className }) {
  const values = useWatch({ control, name }) || {};
  const { rowTotals, columnTotals, total } = sumMatrix(values, rows, columns);
  const tableRef = useRef(null);

  const move = (event, rowIndex, columnIndex) => {
    const step = event.key === "ArrowUp" ? -1 : event.key === "ArrowDown" || event.key === "Enter" ? 1 : 0;
    if (!step) return;
    const next = tableRef.current?.querySelector(`[data-matrix-cell="${rowIndex + step}-${columnIndex}"]`);
    if (!next) return;
    event.preventDefault();
    next.focus();
    next.select?.();
  };

  return <div ref={tableRef} className={cn("overflow-x-auto rounded-lg border", className)}>
    <Table>
      {caption && <caption className="sr-only">{caption}</caption>}
      <TableHeader className="bg-muted/50">
        <TableRow className="hover:bg-transparent">
          <TableHead className="sticky left-0 z-10 min-w-32 bg-muted pl-4">{rowLabel} / size</TableHead>
          {columns.map((column) => <TableHead key={column.id} className="min-w-24 text-right">{column.label}</TableHead>)}
          <TableHead className="min-w-24 pr-4 text-right">Total</TableHead>
        </TableRow>
      </TableHeader>
      <TableBody>
        {rows.map((row, rowIndex) => <TableRow key={row.id} className="hover:bg-transparent">
          <TableCell className="sticky left-0 z-10 bg-card pl-4 font-medium">
            <div className="grid">
              <span>{row.label}</span>
              {row.hint && <span className="text-xs font-normal text-muted-foreground">{row.hint}</span>}
            </div>
          </TableCell>
          {columns.map((column, columnIndex) => {
            const key = matrixCellKey(row.id, column.id);
            return <TableCell key={column.id} className="py-1.5 text-right align-top">
              {readOnly
                ? <span className={cn("tabular-nums", !toNumber(values[key]) && "text-muted-foreground")}>{toNumber(values[key]) ? formatNumber(toNumber(values[key])) : "—"}</span>
                : <Controller control={control} name={`${name}.${key}`} render={({ field, fieldState }) => <div className="grid justify-items-end gap-1">
                  <Input
                    {...field}
                    value={field.value ?? ""}
                    type="number"
                    min="0"
                    step="any"
                    inputMode="numeric"
                    placeholder="0"
                    data-matrix-cell={`${rowIndex}-${columnIndex}`}
                    aria-label={`${row.label}, size ${column.label}, quantity in ${unit}`}
                    aria-invalid={fieldState.invalid}
                    onKeyDown={(event) => move(event, rowIndex, columnIndex)}
                    onFocus={(event) => event.target.select()}
                    className="h-8 w-24 text-right tabular-nums"
                  />
                  {fieldState.error && <span className="text-xs text-destructive" role="alert">{fieldState.error.message}</span>}
                </div>} />}
            </TableCell>;
          })}
          <TableCell className="pr-4 text-right font-medium tabular-nums">{formatNumber(rowTotals[row.id] || 0)}</TableCell>
        </TableRow>)}
      </TableBody>
      <TableFooter className="bg-muted/50">
        <TableRow className="hover:bg-transparent">
          <TableCell className="sticky left-0 z-10 bg-muted pl-4 font-medium">Total</TableCell>
          {columns.map((column) => <TableCell key={column.id} className="text-right font-medium tabular-nums">{formatNumber(columnTotals[column.id] || 0)}</TableCell>)}
          <TableCell className="pr-4 text-right font-semibold tabular-nums">{formatNumber(total)} {unit}</TableCell>
        </TableRow>
      </TableFooter>
    </Table>
  </div>;
}
