'use client'

/**
 * StepAnsicht — Read-only page layout preview.
 *
 * Shows the reconstructed page with all zones (content grid + embedded boxes)
 * positioned at their original coordinates. Pure CSS positioning, no canvas.
 */

import { useCallback, useEffect, useRef, useState } from 'react'
import { useGridEditor } from '@/components/grid-editor/useGridEditor'
import type { GridZone, GridEditorCell } from '@/components/grid-editor/types'

const KLAUSUR_API = '/klausur-api'

interface StepAnsichtProps {
  sessionId: string | null
  onNext: () => void
}

/** Get dominant color from a cell's word_boxes or color_override. */
function getCellColor(cell: GridEditorCell | undefined): string | null {
  if (!cell) return null
  if ((cell as any).color_override) return (cell as any).color_override
  const colored = cell.word_boxes?.find((wb) => wb.color_name && wb.color_name !== 'black')
  return colored?.color ?? null
}

export function StepAnsicht({ sessionId, onNext }: StepAnsichtProps) {
  const {
    grid,
    loading,
    error,
    loadGrid,
  } = useGridEditor(sessionId)

  const containerRef = useRef<HTMLDivElement>(null)
  const [containerWidth, setContainerWidth] = useState(0)
  const [showOriginal, setShowOriginal] = useState(false)

  // Load grid on mount
  useEffect(() => {
    if (sessionId) loadGrid()
  }, [sessionId]) // eslint-disable-line react-hooks/exhaustive-deps

  // Track container width
  useEffect(() => {
    if (!containerRef.current) return
    const ro = new ResizeObserver(([entry]) => {
      setContainerWidth(entry.contentRect.width)
    })
    ro.observe(containerRef.current)
    return () => ro.disconnect()
  }, [])

  if (loading) {
    return (
      <div className="flex items-center justify-center py-16">
        <div className="w-8 h-8 border-4 border-teal-500 border-t-transparent rounded-full animate-spin" />
        <span className="ml-3 text-gray-500">Lade Vorschau...</span>
      </div>
    )
  }

  if (error || !grid) {
    return (
      <div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-8 text-center">
        <p className="text-red-500 mb-4">{error || 'Keine Grid-Daten vorhanden.'}</p>
        <button onClick={onNext} className="px-5 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 text-sm font-medium">
          Weiter →
        </button>
      </div>
    )
  }

  const imgW = grid.image_width || 1
  const imgH = grid.image_height || 1
  const scale = containerWidth > 0 ? containerWidth / imgW : 1
  const containerHeight = imgH * scale

  // Font size: scale from original, with minimum
  const baseFontPx = (grid as any).layout_metrics?.font_size_suggestion_px || 14
  const scaledFont = Math.max(7, baseFontPx * scale * 0.85)

  return (
    <div className="space-y-3">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h3 className="text-lg font-semibold text-gray-900 dark:text-white">
            Ansicht — Seitenrekonstruktion
          </h3>
          <p className="text-sm text-gray-500 dark:text-gray-400">
            Vorschau der rekonstruierten Seite mit allen Zonen und Boxen an Originalpositionen.
          </p>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => setShowOriginal(!showOriginal)}
            className={`px-3 py-1.5 rounded-lg text-xs font-medium transition-colors ${
              showOriginal
                ? 'bg-teal-100 text-teal-700 dark:bg-teal-900/40 dark:text-teal-300'
                : 'bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300'
            }`}
          >
            {showOriginal ? 'Original ausblenden' : 'Original einblenden'}
          </button>
          <button
            onClick={onNext}
            className="px-5 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 text-sm font-medium"
          >
            Weiter →
          </button>
        </div>
      </div>

      {/* Page container */}
      <div
        ref={containerRef}
        className="relative bg-white dark:bg-gray-900 border border-gray-300 dark:border-gray-600 rounded-lg overflow-hidden shadow-lg"
        style={{ height: containerHeight > 0 ? `${containerHeight}px` : 'auto' }}
      >
        {/* Original image background (toggleable) */}
        {showOriginal && sessionId && (
          <img
            src={`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/cropped`}
            alt="Original"
            className="absolute inset-0 w-full h-full object-contain opacity-15"
          />
        )}

        {/* Render zones */}
        {grid.zones.map((zone) => (
          <ZoneRenderer
            key={zone.zone_index}
            zone={zone}
            scale={scale}
            fontSize={scaledFont}
          />
        ))}
      </div>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Zone renderer
// ---------------------------------------------------------------------------

function ZoneRenderer({ zone, scale, fontSize }: {
  zone: GridZone
  scale: number
  fontSize: number
}) {
  const isBox = zone.zone_type === 'box'
  const boxColor = (zone as any).box_bg_hex || '#6b7280'

  if (!zone.cells || zone.cells.length === 0) return null

  const left = zone.bbox_px.x * scale
  const top = zone.bbox_px.y * scale
  const width = zone.bbox_px.w * scale
  const height = zone.bbox_px.h * scale

  // Build cell map
  const cellMap = new Map<string, GridEditorCell>()
  for (const cell of zone.cells) {
    cellMap.set(`${cell.row_index}_${cell.col_index}`, cell)
  }

  // Column widths (relative to zone)
  const colWidths = zone.columns.map((col) => {
    const w = (col.x_max_px ?? 0) - (col.x_min_px ?? 0)
    return Math.max(10, w * scale)
  })
  const totalColW = colWidths.reduce((s, w) => s + w, 0)
  // Scale columns to fit zone width
  const colScale = totalColW > 0 ? width / totalColW : 1
  const scaledColWidths = colWidths.map((w) => w * colScale)

  const gridTemplateCols = scaledColWidths.map((w) => `${w.toFixed(1)}px`).join(' ')
  const numCols = zone.columns.length

  return (
    <div
      className="absolute overflow-hidden"
      style={{
        left: `${left}px`,
        top: `${top}px`,
        width: `${width}px`,
        minHeight: `${height}px`,
        border: isBox ? `${Math.max(2, 3 * scale)}px solid ${boxColor}` : undefined,
        backgroundColor: isBox ? `${boxColor}08` : undefined,
        borderRadius: isBox ? `${Math.max(2, 4 * scale)}px` : undefined,
        fontSize: `${fontSize}px`,
        lineHeight: '1.3',
      }}
    >
      <div
        className="w-full"
        style={{
          display: 'grid',
          gridTemplateColumns: gridTemplateCols,
        }}
      >
        {zone.rows.map((row) => {
          const isSpanning = zone.cells.some(
            (c) => c.row_index === row.index && c.col_type === 'spanning_header',
          )

          // Row height from measured px
          const measuredH = (row.y_max_px ?? 0) - (row.y_min_px ?? 0)
          const rowH = Math.max(fontSize * 1.4, measuredH * scale)

          return (
            <div key={row.index} style={{ display: 'contents' }}>
              {isSpanning ? (
                // Render spanning cells
                zone.cells
                  .filter((c) => c.row_index === row.index && c.col_type === 'spanning_header')
                  .sort((a, b) => a.col_index - b.col_index)
                  .map((cell) => {
                    const colspan = (cell as any).colspan || numCols
                    const gridColStart = cell.col_index + 1
                    const gridColEnd = gridColStart + colspan
                    const color = getCellColor(cell)
                    return (
                      <div
                        key={cell.cell_id}
                        className={`px-1 overflow-hidden ${row.is_header ? 'font-bold' : ''}`}
                        style={{
                          gridColumn: `${gridColStart} / ${gridColEnd}`,
                          minHeight: `${rowH}px`,
                          color: color || undefined,
                          whiteSpace: 'pre-wrap',
                        }}
                      >
                        {cell.text}
                      </div>
                    )
                  })
              ) : (
                // Render normal columns
                zone.columns.map((col) => {
                  const cell = cellMap.get(`${row.index}_${col.index}`)
                  if (!cell) {
                    return <div key={col.index} style={{ minHeight: `${rowH}px` }} />
                  }
                  const color = getCellColor(cell)
                  const isBold = col.bold || cell.is_bold || row.is_header
                  const text = cell.text ?? ''
                  const isMultiLine = text.includes('\n')

                  return (
                    <div
                      key={col.index}
                      className={`px-1 overflow-hidden ${isBold ? 'font-bold' : ''}`}
                      style={{
                        minHeight: `${rowH}px`,
                        color: color || undefined,
                        whiteSpace: isMultiLine ? 'pre-wrap' : 'nowrap',
                        textOverflow: isMultiLine ? undefined : 'ellipsis',
                      }}
                    >
                      {text}
                    </div>
                  )
                })
              )}
            </div>
          )
        })}
      </div>
    </div>
  )
}
