'use client'

/**
 * GridOverlay Component
 *
 * SVG overlay for displaying detected OCR grid structure on document images.
 * Features:
 * - Cell status visualization (recognized/problematic/manual/empty)
 * - 1mm grid overlay for A4 pages (210x297mm)
 * - Text at original bounding-box positions
 * - Editable text (contentEditable) at original positions
 * - Click-to-edit for cells
 */

import { useCallback, useState } from 'react'
import { cn } from '@/lib/utils'

export type CellStatus = 'empty' | 'recognized' | 'problematic' | 'manual'

export interface GridCell {
  row: number
  col: number
  x: number      // X position as percentage (0-100)
  y: number      // Y position as percentage (0-100)
  width: number  // Width as percentage (0-100)
  height: number // Height as percentage (0-100)
  text: string
  confidence: number
  status: CellStatus
  column_type?: 'english' | 'german' | 'example' | 'unknown'
  x_mm?: number
  y_mm?: number
  width_mm?: number
  height_mm?: number
}

export interface GridData {
  rows: number
  columns: number
  cells: GridCell[][]
  column_types: string[]
  column_boundaries: number[]
  row_boundaries: number[]
  deskew_angle: number
  stats: {
    recognized: number
    problematic: number
    empty: number
    manual?: number
    total: number
    coverage: number
  }
  page_dimensions?: {
    width_mm: number
    height_mm: number
    format: string
  }
  source?: string
}

interface GridOverlayProps {
  grid: GridData
  imageUrl?: string
  onCellClick?: (cell: GridCell) => void
  onCellTextChange?: (cell: GridCell, newText: string) => void
  selectedCell?: GridCell | null
  showEmpty?: boolean
  showLabels?: boolean
  showNumbers?: boolean
  showTextLabels?: boolean
  showMmGrid?: boolean
  showTextAtPosition?: boolean
  editableText?: boolean
  highlightedBlockNumber?: number | null
  className?: string
}

// Status colors
const STATUS_COLORS = {
  recognized: {
    fill: 'rgba(34, 197, 94, 0.2)',
    stroke: '#22c55e',
    hoverFill: 'rgba(34, 197, 94, 0.3)',
  },
  problematic: {
    fill: 'rgba(249, 115, 22, 0.3)',
    stroke: '#f97316',
    hoverFill: 'rgba(249, 115, 22, 0.4)',
  },
  manual: {
    fill: 'rgba(59, 130, 246, 0.2)',
    stroke: '#3b82f6',
    hoverFill: 'rgba(59, 130, 246, 0.3)',
  },
  empty: {
    fill: 'transparent',
    stroke: 'rgba(148, 163, 184, 0.3)',
    hoverFill: 'rgba(148, 163, 184, 0.1)',
  },
}

// A4 dimensions for mm grid
const A4_WIDTH_MM = 210
const A4_HEIGHT_MM = 297

// Helper to calculate block number (1-indexed, row-by-row)
export function getCellBlockNumber(cell: GridCell, grid: GridData): number {
  return cell.row * grid.columns + cell.col + 1
}

/**
 * 1mm Grid SVG Lines for A4 format.
 * Renders inside a viewBox="0 0 100 100" (percentage-based).
 */
function MmGridLines() {
  const lines: React.ReactNode[] = []

  // Vertical lines: 210 lines for 210mm
  for (let mm = 0; mm <= A4_WIDTH_MM; mm++) {
    const x = (mm / A4_WIDTH_MM) * 100
    const isCm = mm % 10 === 0
    lines.push(
      <line
        key={`v-${mm}`}
        x1={x}
        y1={0}
        x2={x}
        y2={100}
        stroke={isCm ? 'rgba(59, 130, 246, 0.25)' : 'rgba(59, 130, 246, 0.1)'}
        strokeWidth={isCm ? 0.08 : 0.03}
      />
    )
  }

  // Horizontal lines: 297 lines for 297mm
  for (let mm = 0; mm <= A4_HEIGHT_MM; mm++) {
    const y = (mm / A4_HEIGHT_MM) * 100
    const isCm = mm % 10 === 0
    lines.push(
      <line
        key={`h-${mm}`}
        x1={0}
        y1={y}
        x2={100}
        y2={y}
        stroke={isCm ? 'rgba(59, 130, 246, 0.25)' : 'rgba(59, 130, 246, 0.1)'}
        strokeWidth={isCm ? 0.08 : 0.03}
      />
    )
  }

  return <g style={{ pointerEvents: 'none' }}>{lines}</g>
}

/**
 * Positioned text overlay using absolute-positioned HTML divs.
 * Each cell's text appears at its bounding-box position with matching font size.
 */
function PositionedTextLayer({
  cells,
  editable,
  onTextChange,
}: {
  cells: GridCell[]
  editable: boolean
  onTextChange?: (cell: GridCell, text: string) => void
}) {
  const [hoveredCell, setHoveredCell] = useState<string | null>(null)

  return (
    <div className="absolute inset-0" style={{ pointerEvents: editable ? 'auto' : 'none' }}>
      {cells.map((cell) => {
        if (cell.status === 'empty' || !cell.text) return null

        const cellKey = `pos-${cell.row}-${cell.col}`
        const isHovered = hoveredCell === cellKey
        // Estimate font size from cell height: height_pct maps to roughly pt size
        // A4 at 100% = 297mm height. Cell height in % * 297mm / 100 = height_mm
        // Font size ~= height_mm * 2.2 (roughly matching print)
        const heightMm = cell.height_mm ?? (cell.height / 100 * A4_HEIGHT_MM)
        const fontSizePt = Math.max(6, Math.min(18, heightMm * 2.2))

        return (
          <div
            key={cellKey}
            className={cn(
              'absolute overflow-hidden transition-colors duration-100',
              editable && 'cursor-text hover:bg-yellow-100/40',
              isHovered && !editable && 'bg-blue-100/30',
            )}
            style={{
              left: `${cell.x}%`,
              top: `${cell.y}%`,
              width: `${cell.width}%`,
              height: `${cell.height}%`,
              fontSize: `${fontSizePt}pt`,
              fontFamily: '"Georgia", "Times New Roman", serif',
              lineHeight: 1.1,
              color: cell.status === 'manual' ? '#1e40af' : '#1a1a1a',
              padding: '0 1px',
              display: 'flex',
              alignItems: 'center',
            }}
            onMouseEnter={() => setHoveredCell(cellKey)}
            onMouseLeave={() => setHoveredCell(null)}
          >
            {editable ? (
              <span
                contentEditable
                suppressContentEditableWarning
                className="outline-none w-full"
                style={{ minHeight: '1em' }}
                onBlur={(e) => {
                  const newText = e.currentTarget.textContent ?? ''
                  if (newText !== cell.text && onTextChange) {
                    onTextChange(cell, newText)
                  }
                }}
              >
                {cell.text}
              </span>
            ) : (
              <span className="truncate">{cell.text}</span>
            )}
          </div>
        )
      })}
    </div>
  )
}

export function GridOverlay({
  grid,
  imageUrl,
  onCellClick,
  onCellTextChange,
  selectedCell,
  showEmpty = false,
  showLabels = true,
  showNumbers = false,
  showTextLabels = false,
  showMmGrid = false,
  showTextAtPosition = false,
  editableText = false,
  highlightedBlockNumber,
  className,
}: GridOverlayProps) {
  const handleCellClick = useCallback(
    (cell: GridCell) => {
      if (onCellClick && cell.status !== 'empty') {
        onCellClick(cell)
      }
    },
    [onCellClick]
  )

  const flatCells = grid.cells.flat()

  return (
    <div className={cn('relative', className)}>
      {/* Background image */}
      {imageUrl && (
        <img
          src={imageUrl}
          alt="Document"
          className="w-full h-auto"
        />
      )}

      {/* SVG overlay */}
      <svg
        className="absolute inset-0 w-full h-full"
        style={{ pointerEvents: 'none' }}
        viewBox="0 0 100 100"
        preserveAspectRatio="none"
      >
        {/* 1mm Grid */}
        {showMmGrid && <MmGridLines />}

        {/* Column type labels */}
        {showLabels && grid.column_types.length > 0 && (
          <g>
            {grid.column_types.map((type, idx) => {
              const x = grid.column_boundaries[idx]
              const width = grid.column_boundaries[idx + 1] - x
              const label = type === 'english' ? 'EN' : type === 'german' ? 'DE' : type === 'example' ? 'Ex' : '?'
              return (
                <text
                  key={`col-label-${idx}`}
                  x={x + width / 2}
                  y={1.5}
                  textAnchor="middle"
                  fontSize="1.5"
                  fill="#64748b"
                  fontWeight="bold"
                  style={{ pointerEvents: 'none' }}
                >
                  {label}
                </text>
              )
            })}
          </g>
        )}

        {/* Grid cells (skip if showing text at position to avoid double rendering) */}
        {!showTextAtPosition && flatCells.map((cell) => {
          const colors = STATUS_COLORS[cell.status]
          const isSelected = selectedCell?.row === cell.row && selectedCell?.col === cell.col
          const isClickable = cell.status !== 'empty' && onCellClick
          const blockNumber = getCellBlockNumber(cell, grid)
          const isHighlighted = highlightedBlockNumber === blockNumber

          if (!showEmpty && cell.status === 'empty') {
            return null
          }

          return (
            <g
              key={`cell-${cell.row}-${cell.col}`}
              style={{ pointerEvents: isClickable ? 'auto' : 'none' }}
              onClick={() => handleCellClick(cell)}
              className={isClickable ? 'cursor-pointer' : ''}
            >
              <rect
                x={cell.x}
                y={cell.y}
                width={cell.width}
                height={cell.height}
                fill={isHighlighted ? 'rgba(99, 102, 241, 0.3)' : colors.fill}
                stroke={isSelected || isHighlighted ? '#4f46e5' : colors.stroke}
                strokeWidth={isSelected || isHighlighted ? 0.3 : 0.15}
                rx={0.2}
                className={cn(
                  'transition-all duration-150',
                  isClickable && 'hover:fill-opacity-40'
                )}
              />

              {showNumbers && cell.status !== 'empty' && (
                <>
                  <rect
                    x={cell.x + 0.3}
                    y={cell.y + 0.3}
                    width={2.5}
                    height={1.8}
                    fill={isHighlighted ? '#4f46e5' : '#374151'}
                    rx={0.3}
                  />
                  <text
                    x={cell.x + 1.55}
                    y={cell.y + 1.5}
                    textAnchor="middle"
                    fontSize="1.2"
                    fill="white"
                    fontWeight="bold"
                    style={{ pointerEvents: 'none' }}
                  >
                    {blockNumber}
                  </text>
                </>
              )}

              {!showNumbers && !showTextLabels && cell.status !== 'empty' && (
                <circle
                  cx={cell.x + 0.8}
                  cy={cell.y + 0.8}
                  r={0.5}
                  fill={colors.stroke}
                  stroke="white"
                  strokeWidth={0.1}
                />
              )}

              {showTextLabels && (cell.status === 'recognized' || cell.status === 'manual') && cell.text && (
                <text
                  x={cell.x + cell.width / 2}
                  y={cell.y + cell.height / 2 + Math.min(cell.height * 0.2, 0.5)}
                  textAnchor="middle"
                  fontSize={Math.min(cell.height * 0.5, 1.4)}
                  fill={cell.status === 'manual' ? '#1e40af' : '#166534'}
                  fontWeight="500"
                  style={{ pointerEvents: 'none' }}
                >
                  {cell.text.length > 15 ? cell.text.slice(0, 15) + '\u2026' : cell.text}
                </text>
              )}

              {cell.status === 'recognized' && cell.confidence < 0.7 && (
                <text
                  x={cell.x + cell.width - 0.5}
                  y={cell.y + 1.2}
                  fontSize="0.8"
                  fill="#f97316"
                  style={{ pointerEvents: 'none' }}
                >
                  !
                </text>
              )}

              {isSelected && (
                <rect
                  x={cell.x}
                  y={cell.y}
                  width={cell.width}
                  height={cell.height}
                  fill="none"
                  stroke="#4f46e5"
                  strokeWidth={0.4}
                  strokeDasharray="0.5,0.3"
                  rx={0.2}
                />
              )}
            </g>
          )
        })}

        {/* Show cell outlines when in positioned text mode */}
        {showTextAtPosition && flatCells.map((cell) => {
          if (cell.status === 'empty') return null
          return (
            <rect
              key={`outline-${cell.row}-${cell.col}`}
              x={cell.x}
              y={cell.y}
              width={cell.width}
              height={cell.height}
              fill="none"
              stroke="rgba(99, 102, 241, 0.2)"
              strokeWidth={0.08}
              rx={0.1}
              style={{ pointerEvents: 'none' }}
            />
          )
        })}

        {/* Row boundaries */}
        {grid.row_boundaries.map((y, idx) => (
          <line
            key={`row-line-${idx}`}
            x1={0}
            y1={y}
            x2={100}
            y2={y}
            stroke="rgba(148, 163, 184, 0.2)"
            strokeWidth={0.05}
            style={{ pointerEvents: 'none' }}
          />
        ))}

        {/* Column boundaries */}
        {grid.column_boundaries.map((x, idx) => (
          <line
            key={`col-line-${idx}`}
            x1={x}
            y1={0}
            x2={x}
            y2={100}
            stroke="rgba(148, 163, 184, 0.2)"
            strokeWidth={0.05}
            style={{ pointerEvents: 'none' }}
          />
        ))}
      </svg>

      {/* Positioned text HTML overlay (outside SVG for proper text rendering) */}
      {showTextAtPosition && (
        <PositionedTextLayer
          cells={flatCells.filter(c => c.status !== 'empty' && c.text)}
          editable={editableText}
          onTextChange={onCellTextChange}
        />
      )}
    </div>
  )
}

// Re-export widgets from sibling file for backwards compatibility
export { GridStats, GridLegend } from './GridOverlayWidgets'
