"use client";

import { cn } from "@/lib/utils";
import type { GridState, GridPointerState } from "@/lib/visualizations/types";
import { GridCell } from "../primitives/grid-cell";

interface GridViewProps {
  grid: GridState;
  pointers?: GridPointerState[];
  cellSize?: "sm" | "md" | "lg";
  showColLabels?: boolean;
  showRowLabels?: boolean;
  className?: string;
}

const CELL_WIDTHS = {
  sm: 40,
  md: 56,
  lg: 72,
} as const;

const CELL_GAPS = {
  sm: 2,
  md: 4,
  lg: 6,
} as const;

const POINTER_COLORS = {
  current: "border-blue-500 text-blue-500",
  dependency: "border-amber-500 text-amber-500",
  result: "border-green-500 text-green-500",
  default: "border-[var(--primary)] text-[var(--primary)]",
} as const;

export function GridView({
  grid,
  pointers = [],
  cellSize = "sm",
  showColLabels = true,
  showRowLabels = false,
  className,
}: GridViewProps) {
  const cellWidth = CELL_WIDTHS[cellSize];
  const gap = CELL_GAPS[cellSize];

  // For 1D grids (single row), flatten for easier rendering
  const is1D = grid.cells.length === 1;

  // Calculate pointer positions for highlighting
  const pointerPositions = new Map<string, GridPointerState>();
  for (const pointer of pointers) {
    const key = `${pointer.row}-${pointer.col}`;
    pointerPositions.set(key, pointer);
  }

  return (
    <div className={cn("flex flex-col items-center", className)}>
      {grid.label && (
        <span className="mb-2 text-sm font-medium text-[var(--muted-foreground)]">
          {grid.label}
        </span>
      )}

      {/* Column labels */}
      {showColLabels && grid.colLabels && (
        <div
          className="flex mb-1"
          style={{
            gap: `${gap}px`,
            marginLeft: showRowLabels ? `${cellWidth + gap}px` : 0,
          }}
        >
          {grid.colLabels.map((label, idx) => (
            <div
              key={idx}
              className="flex items-center justify-center text-xs text-[var(--muted-foreground)]"
              style={{ width: `${cellWidth}px` }}
            >
              {label}
            </div>
          ))}
        </div>
      )}

      {/* Grid rows */}
      {is1D ? (
        // 1D grid (single row)
        <div className="relative">
          <div className="flex" style={{ gap: `${gap}px` }}>
            {grid.cells[0].map((cell, colIdx) => {
              const pointer = pointerPositions.get(`0-${colIdx}`);
              return (
                <div key={cell.id} className="relative">
                  {pointer && (
                    <div
                      className={cn(
                        "absolute -top-6 left-1/2 -translate-x-1/2 text-xs font-medium whitespace-nowrap",
                        POINTER_COLORS[pointer.color]
                      )}
                    >
                      {pointer.name}
                    </div>
                  )}
                  <GridCell cell={cell} size={cellSize} />
                </div>
              );
            })}
          </div>
        </div>
      ) : (
        // 2D grid
        <div className="flex flex-col" style={{ gap: `${gap}px` }}>
          {grid.cells.map((row, rowIdx) => (
            <div key={rowIdx} className="flex items-center" style={{ gap: `${gap}px` }}>
              {/* Row label */}
              {showRowLabels && grid.rowLabels && (
                <div
                  className="flex items-center justify-center text-xs text-[var(--muted-foreground)]"
                  style={{ width: `${cellWidth}px` }}
                >
                  {grid.rowLabels[rowIdx]}
                </div>
              )}
              {/* Row cells */}
              {row.map((cell, colIdx) => {
                const pointer = pointerPositions.get(`${rowIdx}-${colIdx}`);
                return (
                  <div key={cell.id} className="relative">
                    {pointer && (
                      <div
                        className={cn(
                          "absolute -top-5 left-1/2 -translate-x-1/2 text-xs font-medium whitespace-nowrap",
                          POINTER_COLORS[pointer.color]
                        )}
                      >
                        {pointer.name}
                      </div>
                    )}
                    <GridCell cell={cell} size={cellSize} />
                  </div>
                );
              })}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}
