"use client";

import { type ReactNode, useCallback, useRef, useState } from "react";

import { StatusBadge } from "@/components/status-badge";
import { formatMetricValue } from "@/lib/format";

export function DataTable({
  columns,
  rows,
  statusColumn,
  onRowClick,
  loading,
  renderCell,
}: {
  columns: string[];
  rows: Record<string, unknown>[];
  statusColumn?: string;
  onRowClick?: (row: Record<string, unknown>, index: number) => void;
  loading?: boolean;
  renderCell?: (row: Record<string, unknown>, column: string, index: number) => ReactNode | undefined;
}) {
  const [activeRow, setActiveRow] = useState(-1);
  const tbodyRef = useRef<HTMLTableSectionElement>(null);

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (rows.length === 0) return;
      if (e.key === "j" || e.key === "ArrowDown") {
        e.preventDefault();
        setActiveRow((i) => Math.min(i + 1, rows.length - 1));
      } else if (e.key === "k" || e.key === "ArrowUp") {
        e.preventDefault();
        setActiveRow((i) => Math.max(i - 1, 0));
      } else if (e.key === "Enter" && activeRow >= 0 && onRowClick) {
        onRowClick(rows[activeRow], activeRow);
      }
    },
    [rows, activeRow, onRowClick],
  );

  return (
    <div className="tableWrap" tabIndex={0} onKeyDown={handleKeyDown}>
      <table className="dataTable">
        <thead>
          <tr>
            {columns.map((column) => (
              <th key={column}>{column}</th>
            ))}
          </tr>
        </thead>
        <tbody ref={tbodyRef}>
          {rows.length === 0 ? (
            <tr>
              <td colSpan={columns.length} className="emptyCell">
                {loading ? "Loading..." : "No rows available."}
              </td>
            </tr>
          ) : null}
          {rows.map((row, index) => (
            <tr
              key={index}
              className={`${onRowClick ? "rowClickable" : ""} ${index === activeRow ? "rowActive" : ""}`}
              onClick={() => {
                setActiveRow(index);
                onRowClick?.(row, index);
              }}
              onMouseEnter={() => setActiveRow(index)}
            >
              {columns.map((column) => (
                <td key={column}>
                  {renderCell?.(row, column, index) ?? (statusColumn === column && typeof row[column] === "string" ? (
                    <StatusBadge
                      label={String(row[column])}
                      tone={statusTone(String(row[column]))}
                    />
                  ) : (
                    formatCell(row[column], column)
                  ))}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function formatCell(value: unknown, context?: string) {
  if (value === null || value === undefined) {
    return "—";
  }
  if (typeof value === "number") {
    return Number.isInteger(value) ? value.toString() : formatMetricValue(value, context);
  }
  if (typeof value === "object") {
    return JSON.stringify(value);
  }
  return String(value);
}

function statusTone(status: string) {
  if (status === "success" || status === "ok" || status === "online") {
    return "ok" as const;
  }
  if (status === "gap" || status === "skipped_existing") {
    return "warn" as const;
  }
  if (status === "failed") {
    return "error" as const;
  }
  return "neutral" as const;
}
