'use client'

/**
 * ImageLayoutEditor — SVG overlay on the original scan image.
 *
 * Shows draggable vertical column dividers and horizontal guidelines
 * (margins, header/footer zones). Double-click to add a column,
 * click the × on a divider to remove it.
 */

import { useCallback, useRef } from 'react'
import type { GridZone, LayoutDividers } from './types'

interface ImageLayoutEditorProps {
  imageUrl: string
  zones: GridZone[]
  imageWidth: number
  layoutDividers?: LayoutDividers
  zoom: number
  onZoomChange: (zoom: number) => void
  onColumnDividerMove: (zoneIndex: number, boundaryIndex: number, newXPct: number) => void
  onHorizontalsChange: (horizontals: LayoutDividers['horizontals']) => void
  onCommitUndo: () => void
  onSplitColumnAt: (zoneIndex: number, xPct: number) => void
  onDeleteColumn: (zoneIndex: number, colIndex: number) => void
}

const HORIZ_COLORS: Record<string, string> = {
  top_margin: 'rgba(239, 68, 68, 0.6)',
  header_bottom: 'rgba(59, 130, 246, 0.6)',
  footer_top: 'rgba(249, 115, 22, 0.6)',
  bottom_margin: 'rgba(239, 68, 68, 0.6)',
}

const HORIZ_LABELS: Record<string, string> = {
  top_margin: 'Rand oben',
  header_bottom: 'Kopfzeile',
  footer_top: 'Fusszeile',
  bottom_margin: 'Rand unten',
}

const HORIZ_DEFAULTS: Record<string, number> = {
  top_margin: 3,
  header_bottom: 10,
  footer_top: 92,
  bottom_margin: 97,
}

function clamp(val: number, min: number, max: number) {
  return Math.max(min, Math.min(max, val))
}

export function ImageLayoutEditor({
  imageUrl,
  zones,
  layoutDividers,
  zoom,
  onZoomChange,
  onColumnDividerMove,
  onHorizontalsChange,
  onCommitUndo,
  onSplitColumnAt,
  onDeleteColumn,
}: ImageLayoutEditorProps) {
  const wrapperRef = useRef<HTMLDivElement>(null)
  const draggingRef = useRef<
    | { type: 'col'; zoneIndex: number; boundaryIndex: number }
    | { type: 'horiz'; key: string }
    | null
  >(null)
  const horizontalsRef = useRef(layoutDividers?.horizontals ?? {})
  horizontalsRef.current = layoutDividers?.horizontals ?? {}

  const horizontals = layoutDividers?.horizontals ?? {}

  // Compute column boundaries for each zone
  const zoneBoundaries = zones.map((zone) => {
    const sorted = [...zone.columns].sort((a, b) => a.index - b.index)
    const boundaries: number[] = []
    if (sorted.length > 0) {
      const hasValidPct = sorted.some((c) => c.x_max_pct > 0)
      if (hasValidPct) {
        boundaries.push(sorted[0].x_min_pct)
        for (const col of sorted) {
          boundaries.push(col.x_max_pct)
        }
      } else {
        // Fallback: evenly distribute within zone bbox
        const zoneX = zone.bbox_pct.x || 0
        const zoneW = zone.bbox_pct.w || 100
        for (let i = 0; i <= sorted.length; i++) {
          boundaries.push(zoneX + (i / sorted.length) * zoneW)
        }
      }
    }
    return { zone, boundaries }
  })

  const startDrag = useCallback(
    (
      info: NonNullable<typeof draggingRef.current>,
      e: React.MouseEvent,
    ) => {
      e.preventDefault()
      e.stopPropagation()
      draggingRef.current = info
      onCommitUndo()

      const handleMove = (ev: MouseEvent) => {
        const wrap = wrapperRef.current
        if (!wrap || !draggingRef.current) return
        const rect = wrap.getBoundingClientRect()
        const xPct = clamp(((ev.clientX - rect.left) / rect.width) * 100, 0, 100)
        const yPct = clamp(((ev.clientY - rect.top) / rect.height) * 100, 0, 100)

        if (draggingRef.current.type === 'col') {
          onColumnDividerMove(
            draggingRef.current.zoneIndex,
            draggingRef.current.boundaryIndex,
            xPct,
          )
        } else {
          onHorizontalsChange({
            ...horizontalsRef.current,
            [draggingRef.current.key]: yPct,
          })
        }
      }

      const handleUp = () => {
        draggingRef.current = null
        document.removeEventListener('mousemove', handleMove)
        document.removeEventListener('mouseup', handleUp)
        document.body.style.cursor = ''
        document.body.style.userSelect = ''
      }

      document.body.style.cursor = info.type === 'col' ? 'col-resize' : 'row-resize'
      document.body.style.userSelect = 'none'
      document.addEventListener('mousemove', handleMove)
      document.addEventListener('mouseup', handleUp)
    },
    [onColumnDividerMove, onHorizontalsChange, onCommitUndo],
  )

  const toggleHorizontal = (key: string) => {
    const current = horizontals[key as keyof typeof horizontals]
    if (current != null) {
      const next = { ...horizontals }
      delete next[key as keyof typeof next]
      onHorizontalsChange(next)
    } else {
      onCommitUndo()
      onHorizontalsChange({
        ...horizontals,
        [key]: HORIZ_DEFAULTS[key],
      })
    }
  }

  const handleDoubleClick = (e: React.MouseEvent) => {
    const wrap = wrapperRef.current
    if (!wrap) return
    const rect = wrap.getBoundingClientRect()
    const xPct = clamp(((e.clientX - rect.left) / rect.width) * 100, 0, 100)
    const yPct = clamp(((e.clientY - rect.top) / rect.height) * 100, 0, 100)

    // Find which zone this click is in
    for (const { zone } of zoneBoundaries) {
      const zy = zone.bbox_pct.y || 0
      const zh = zone.bbox_pct.h || 100
      if (yPct >= zy && yPct <= zy + zh) {
        onSplitColumnAt(zone.zone_index, xPct)
        return
      }
    }
    // Fallback: use first zone
    if (zones.length > 0) {
      onSplitColumnAt(zones[0].zone_index, xPct)
    }
  }

  return (
    <div className="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 overflow-hidden flex flex-col">
      {/* Header */}
      <div className="flex items-center justify-between px-3 py-2 border-b border-gray-100 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50">
        <span className="text-xs font-medium text-gray-600 dark:text-gray-400">
          Layout-Editor
        </span>
        <div className="flex items-center gap-2">
          <button
            onClick={() => onZoomChange(Math.max(50, zoom - 25))}
            className="px-2 py-0.5 text-xs bg-gray-200 dark:bg-gray-700 rounded hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-300"
          >
            -
          </button>
          <span className="text-xs text-gray-500 dark:text-gray-400 w-10 text-center">
            {zoom}%
          </span>
          <button
            onClick={() => onZoomChange(Math.min(300, zoom + 25))}
            className="px-2 py-0.5 text-xs bg-gray-200 dark:bg-gray-700 rounded hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-300"
          >
            +
          </button>
          <button
            onClick={() => onZoomChange(100)}
            className="px-2 py-0.5 text-xs bg-gray-200 dark:bg-gray-700 rounded hover:bg-gray-300 dark:hover:bg-gray-600 text-gray-700 dark:text-gray-300"
          >
            Fit
          </button>
        </div>
      </div>

      {/* Horizontal line toggles */}
      <div className="flex items-center gap-1.5 px-3 py-1.5 border-b border-gray-100 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/30 flex-wrap">
        {Object.entries(HORIZ_LABELS).map(([key, label]) => {
          const isActive = horizontals[key as keyof typeof horizontals] != null
          return (
            <button
              key={key}
              onClick={() => toggleHorizontal(key)}
              className={`px-2 py-0.5 text-[10px] rounded border transition-colors ${
                isActive
                  ? 'font-medium'
                  : 'border-gray-200 dark:border-gray-700 text-gray-400 dark:text-gray-500 hover:text-gray-600 dark:hover:text-gray-400'
              }`}
              style={
                isActive
                  ? {
                      color: HORIZ_COLORS[key],
                      borderColor: HORIZ_COLORS[key] + '80',
                    }
                  : undefined
              }
            >
              {label}
            </button>
          )
        })}
        <span className="text-[10px] text-gray-400 dark:text-gray-500 ml-auto">
          Doppelklick = Spalte einfuegen
        </span>
      </div>

      {/* Scrollable image with SVG overlay */}
      <div className="flex-1 overflow-auto p-2">
        <div
          ref={wrapperRef}
          style={{ width: `${zoom}%`, position: 'relative', maxWidth: 'none' }}
          onDoubleClick={handleDoubleClick}
        >
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img
            src={imageUrl}
            alt="Original scan"
            style={{ width: '100%', display: 'block' }}
            draggable={false}
          />
          {/* SVG overlay */}
          <svg
            style={{
              position: 'absolute',
              top: 0,
              left: 0,
              width: '100%',
              height: '100%',
              pointerEvents: 'none',
            }}
            viewBox="0 0 100 100"
            preserveAspectRatio="none"
          >
            {/* Column boundary lines per zone */}
            {zoneBoundaries.map(({ zone, boundaries }) =>
              boundaries.map((xPct, bi) => {
                const yTop = zone.bbox_pct.y || 0
                const yBottom = (zone.bbox_pct.y || 0) + (zone.bbox_pct.h || 100)
                const isEdge = bi === 0 || bi === boundaries.length - 1
                const isInterior = bi > 0 && bi < boundaries.length - 1
                return (
                  <g key={`z${zone.zone_index}-b${bi}`}>
                    {/* Wide invisible hit area */}
                    <rect
                      x={xPct - 0.8}
                      y={yTop}
                      width={1.6}
                      height={yBottom - yTop}
                      fill="transparent"
                      style={{ cursor: 'col-resize', pointerEvents: 'all' }}
                      onMouseDown={(e) =>
                        startDrag(
                          { type: 'col', zoneIndex: zone.zone_index, boundaryIndex: bi },
                          e,
                        )
                      }
                    />
                    {/* Visible line */}
                    <line
                      x1={xPct}
                      y1={yTop}
                      x2={xPct}
                      y2={yBottom}
                      stroke={isEdge ? 'rgba(20, 184, 166, 0.35)' : 'rgba(20, 184, 166, 0.7)'}
                      strokeWidth={isEdge ? 0.15 : 0.25}
                      strokeDasharray={isEdge ? '0.8,0.4' : '0.5,0.3'}
                      style={{ pointerEvents: 'none' }}
                    />
                    {/* Delete button for interior dividers */}
                    {isInterior && zone.columns.length > 1 && (
                      <g
                        style={{ pointerEvents: 'all', cursor: 'pointer' }}
                        onClick={(e) => {
                          e.stopPropagation()
                          onDeleteColumn(zone.zone_index, bi)
                        }}
                      >
                        <circle
                          cx={xPct}
                          cy={Math.max(yTop + 1.5, 1.5)}
                          r={1.2}
                          fill="rgba(239, 68, 68, 0.8)"
                        />
                        <text
                          x={xPct}
                          y={Math.max(yTop + 1.5, 1.5) + 0.5}
                          textAnchor="middle"
                          fill="white"
                          fontSize="1.4"
                          fontWeight="bold"
                          style={{ pointerEvents: 'none' }}
                        >
                          x
                        </text>
                      </g>
                    )}
                  </g>
                )
              }),
            )}

            {/* Horizontal guideline lines */}
            {Object.entries(horizontals).map(([key, yPct]) => {
              if (yPct == null) return null
              const color = HORIZ_COLORS[key] ?? 'rgba(156, 163, 175, 0.6)'
              return (
                <g key={`horiz-${key}`}>
                  {/* Wide invisible hit area */}
                  <rect
                    x={0}
                    y={yPct - 0.6}
                    width={100}
                    height={1.2}
                    fill="transparent"
                    style={{ cursor: 'row-resize', pointerEvents: 'all' }}
                    onMouseDown={(e) => startDrag({ type: 'horiz', key }, e)}
                  />
                  {/* Visible line */}
                  <line
                    x1={0}
                    y1={yPct}
                    x2={100}
                    y2={yPct}
                    stroke={color}
                    strokeWidth={0.2}
                    strokeDasharray="1,0.5"
                    style={{ pointerEvents: 'none' }}
                  />
                  {/* Label */}
                  <text
                    x={1}
                    y={yPct - 0.5}
                    fill={color}
                    fontSize="1.6"
                    style={{ pointerEvents: 'none' }}
                  >
                    {HORIZ_LABELS[key]}
                  </text>
                </g>
              )
            })}
          </svg>
        </div>
      </div>
    </div>
  )
}
