'use client'

/**
 * GroundTruthPanel — Step-through UI for labeling OCR ground truth.
 *
 * Shows page image with SVG overlay (color-coded bounding boxes),
 * alongside crops of the current entry and editable text fields.
 * Keyboard-driven: Enter=confirm, Tab=skip, Arrow keys=navigate.
 */

import { useState, useEffect, useCallback, useRef } from 'react'

import type { GTEntry, GroundTruthPanelProps } from './ground-truth-types'
import { KLAUSUR_API, STATUS_COLORS, getEntryColor } from './ground-truth-types'
import { GTImageCrop } from './GTImageCrop'
import { GroundTruthSummary } from './GroundTruthSummary'

// ---------- Main Component ----------

export function GroundTruthPanel({ sessionId, selectedPage, pageImageUrl }: GroundTruthPanelProps) {
  // State
  const [entries, setEntries] = useState<GTEntry[]>([])
  const [currentIndex, setCurrentIndex] = useState(0)
  const [loading, setLoading] = useState(false)
  const [saving, setSaving] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [imageNatural, setImageNatural] = useState({ w: 0, h: 0 })
  const [showSummary, setShowSummary] = useState(false)
  const [savedMessage, setSavedMessage] = useState<string | null>(null)
  const [isFullscreen, setIsFullscreen] = useState(false)
  const [imageUrl, setImageUrl] = useState(pageImageUrl)
  const [deskewAngle, setDeskewAngle] = useState<number | null>(null)

  // Editable fields for current entry
  const [editEn, setEditEn] = useState('')
  const [editDe, setEditDe] = useState('')
  const [editEx, setEditEx] = useState('')

  const panelRef = useRef<HTMLDivElement>(null)
  const enInputRef = useRef<HTMLInputElement>(null)

  // Reset image URL when page changes
  useEffect(() => {
    setImageUrl(pageImageUrl)
    setDeskewAngle(null)
  }, [pageImageUrl])

  // Load natural image dimensions
  useEffect(() => {
    if (!imageUrl) return
    const img = new Image()
    img.onload = () => setImageNatural({ w: img.naturalWidth, h: img.naturalHeight })
    img.src = imageUrl
  }, [imageUrl])

  // Sync edit fields when current entry changes
  useEffect(() => {
    const entry = entries[currentIndex]
    if (entry) {
      setEditEn(entry.english)
      setEditDe(entry.german)
      setEditEx(entry.example)
    }
  }, [currentIndex, entries])

  // ---------- Actions ----------

  const handleExtract = useCallback(async () => {
    setLoading(true)
    setError(null)
    setShowSummary(false)
    setSavedMessage(null)
    try {
      const res = await fetch(`${KLAUSUR_API}/api/v1/vocab/sessions/${sessionId}/extract-with-boxes/${selectedPage}`, {
        method: 'POST',
      })
      if (!res.ok) {
        const err = await res.json().catch(() => ({ detail: res.statusText }))
        throw new Error(err.detail || 'Extract failed')
      }
      const data = await res.json()
      const loaded: GTEntry[] = (data.entries || []).map((e: GTEntry) => ({ ...e, status: 'pending' as const }))
      setEntries(loaded)
      setCurrentIndex(0)

      // Switch to deskewed image if available
      if (data.deskewed) {
        setImageUrl(`${KLAUSUR_API}/api/v1/vocab/sessions/${sessionId}/deskewed-image/${selectedPage}`)
        setDeskewAngle(data.deskew_angle)
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Extraction failed')
    } finally {
      setLoading(false)
    }
  }, [sessionId, selectedPage])

  const confirmEntry = useCallback(() => {
    if (entries.length === 0) return
    const entry = entries[currentIndex]
    const isEdited = editEn !== entry.english || editDe !== entry.german || editEx !== entry.example
    const updated = [...entries]
    updated[currentIndex] = {
      ...entry,
      english: editEn,
      german: editDe,
      example: editEx,
      status: isEdited ? 'edited' : 'confirmed',
    }
    setEntries(updated)
    if (currentIndex < entries.length - 1) {
      setCurrentIndex(currentIndex + 1)
    } else {
      setShowSummary(true)
    }
  }, [entries, currentIndex, editEn, editDe, editEx])

  const skipEntry = useCallback(() => {
    if (entries.length === 0) return
    const updated = [...entries]
    updated[currentIndex] = { ...updated[currentIndex], status: 'skipped' }
    setEntries(updated)
    if (currentIndex < entries.length - 1) {
      setCurrentIndex(currentIndex + 1)
    } else {
      setShowSummary(true)
    }
  }, [entries, currentIndex])

  const goTo = useCallback((idx: number) => {
    if (idx >= 0 && idx < entries.length) {
      setCurrentIndex(idx)
      setShowSummary(false)
    }
  }, [entries.length])

  const handleSave = useCallback(async () => {
    setSaving(true)
    setError(null)
    try {
      const res = await fetch(`${KLAUSUR_API}/api/v1/vocab/sessions/${sessionId}/ground-truth/${selectedPage}`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ entries }),
      })
      if (!res.ok) throw new Error('Save failed')
      const data = await res.json()
      setSavedMessage(`Gespeichert: ${data.confirmed} bestaetigt, ${data.edited} editiert, ${data.skipped} uebersprungen`)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Save failed')
    } finally {
      setSaving(false)
    }
  }, [sessionId, selectedPage, entries])

  // ---------- Keyboard shortcuts ----------

  useEffect(() => {
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'Escape' && isFullscreen) {
        e.preventDefault()
        setIsFullscreen(false)
        return
      }

      if (entries.length === 0 || showSummary) return

      // Don't capture when typing in inputs
      const tag = (e.target as HTMLElement)?.tagName
      const isInput = tag === 'INPUT' || tag === 'TEXTAREA'

      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault()
        confirmEntry()
      } else if (e.key === 'Tab' && !e.shiftKey) {
        if (!isInput) {
          e.preventDefault()
          skipEntry()
        }
      } else if (e.key === 'ArrowLeft' && !isInput) {
        e.preventDefault()
        goTo(currentIndex - 1)
      } else if (e.key === 'ArrowRight' && !isInput) {
        e.preventDefault()
        goTo(currentIndex + 1)
      }
    }

    window.addEventListener('keydown', handler)
    return () => window.removeEventListener('keydown', handler)
  }, [entries.length, showSummary, isFullscreen, confirmEntry, skipEntry, goTo, currentIndex])

  // ---------- Computed ----------

  const currentEntry = entries[currentIndex]
  const confirmedCount = entries.filter(e => e.status === 'confirmed').length
  const editedCount = entries.filter(e => e.status === 'edited').length
  const skippedCount = entries.filter(e => e.status === 'skipped').length
  const processedCount = confirmedCount + editedCount + skippedCount
  const progress = entries.length > 0 ? Math.round((processedCount / entries.length) * 100) : 0

  // ---------- Render: No entries yet ----------

  if (entries.length === 0) {
    return (
      <div className="bg-white rounded-xl border border-slate-200 p-8 text-center" ref={panelRef}>
        <h3 className="text-lg font-semibold text-slate-900 mb-2">Ground Truth Labeling</h3>
        <p className="text-sm text-slate-500 mb-6">
          Erkennung starten um Vokabeln mit Positionen zu extrahieren.
          Danach jede Zeile durchgehen und bestaetigen oder korrigieren.
        </p>
        <button
          onClick={handleExtract}
          disabled={loading}
          className="px-6 py-3 bg-teal-600 text-white rounded-lg font-medium hover:bg-teal-700 disabled:opacity-50 transition-colors"
        >
          {loading ? (
            <span className="flex items-center gap-2">
              <svg className="animate-spin w-5 h-5" fill="none" viewBox="0 0 24 24">
                <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
              </svg>
              Erkennung laeuft...
            </span>
          ) : 'Erkennung starten'}
        </button>
        {error && (
          <div className="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg text-red-700 text-sm">{error}</div>
        )}
      </div>
    )
  }

  // ---------- Render: Summary ----------

  if (showSummary) {
    return (
      <GroundTruthSummary
        entries={entries}
        confirmedCount={confirmedCount}
        editedCount={editedCount}
        skippedCount={skippedCount}
        saving={saving}
        savedMessage={savedMessage}
        error={error}
        isFullscreen={isFullscreen}
        onSave={handleSave}
        onRestart={() => { setShowSummary(false); setCurrentIndex(0) }}
        onToggleFullscreen={() => setIsFullscreen(!isFullscreen)}
        onGoTo={goTo}
      />
    )
  }

  // ---------- Render: Main Review UI ----------

  return (
    <div className={`bg-white rounded-xl border border-slate-200 overflow-hidden ${
      isFullscreen ? 'fixed inset-0 z-50 overflow-auto m-0 rounded-none bg-white' : ''
    }`} ref={panelRef}>
      {/* Header with progress + fullscreen toggle */}
      <div className="flex items-center gap-2 px-4 pt-2">
        <div className="flex-1 h-1.5 bg-slate-100 rounded-full">
          <div
            className="h-full bg-teal-500 transition-all duration-300 rounded-full"
            style={{ width: `${progress}%` }}
          />
        </div>
        <span className="text-xs text-slate-400 whitespace-nowrap">{currentIndex + 1}/{entries.length}</span>
        {deskewAngle !== null && (
          <span className="text-xs text-teal-600 whitespace-nowrap" title="Bild wurde begradigt">
            {deskewAngle.toFixed(1)}&deg;
          </span>
        )}
        <button
          onClick={() => setIsFullscreen(!isFullscreen)}
          className="p-1.5 rounded-lg hover:bg-slate-100 text-slate-500 hover:text-slate-700 transition-colors"
          title={isFullscreen ? 'Vollbild verlassen (Esc)' : 'Vollbild'}
        >
          {isFullscreen ? (
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" d="M9 9V4.5M9 9H4.5M9 9 3.75 3.75M9 15v4.5M9 15H4.5M9 15l-5.25 5.25M15 9h4.5M15 9V4.5M15 9l5.25-5.25M15 15h4.5M15 15v4.5m0-4.5 5.25 5.25" />
            </svg>
          ) : (
            <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" strokeWidth={2} stroke="currentColor">
              <path strokeLinecap="round" strokeLinejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M3.75 20.25v-4.5m0 4.5h4.5m-4.5 0L9 15M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25h-4.5m4.5 0v-4.5m0 4.5L15 15" />
            </svg>
          )}
        </button>
      </div>

      <div className={`flex flex-col ${isFullscreen ? 'lg:flex-row h-[calc(100vh-3rem)]' : 'lg:flex-row'}`}>
        {/* Left: Page image with SVG overlay (2/3) */}
        <div className={`${isFullscreen ? 'lg:w-2/3 p-4 overflow-y-auto h-full' : 'lg:w-2/3 p-4'}`}>
          <div className="relative bg-slate-50 rounded-lg overflow-hidden">
            {imageUrl && (
              <img
                src={imageUrl}
                alt={`Seite ${selectedPage + 1}`}
                className="w-full"
                draggable={false}
              />
            )}
            {/* SVG Overlay */}
            <svg
              viewBox="0 0 100 100"
              preserveAspectRatio="none"
              className="absolute inset-0 w-full h-full"
              style={{ pointerEvents: 'none' }}
            >
              {entries.map((entry, i) => {
                const colors = getEntryColor(entry, i, currentIndex)
                return (
                  <rect
                    key={i}
                    x={entry.bbox.x}
                    y={entry.bbox.y}
                    width={entry.bbox.w}
                    height={entry.bbox.h}
                    fill={colors.fill}
                    stroke={colors.stroke}
                    strokeWidth={i === currentIndex ? 0.3 : 0.15}
                    style={{ cursor: 'pointer', pointerEvents: 'all' }}
                    onClick={() => goTo(i)}
                  />
                )
              })}
            </svg>
          </div>

          {/* Legend */}
          <div className="flex items-center gap-4 mt-3 text-xs text-slate-500">
            <span className="flex items-center gap-1">
              <span className="w-3 h-3 rounded-sm" style={{ background: STATUS_COLORS.current.fill, border: `1px solid ${STATUS_COLORS.current.stroke}` }} /> Aktuell
            </span>
            <span className="flex items-center gap-1">
              <span className="w-3 h-3 rounded-sm" style={{ background: STATUS_COLORS.confirmed.fill, border: `1px solid ${STATUS_COLORS.confirmed.stroke}` }} /> Bestaetigt
            </span>
            <span className="flex items-center gap-1">
              <span className="w-3 h-3 rounded-sm" style={{ background: STATUS_COLORS.edited.fill, border: `1px solid ${STATUS_COLORS.edited.stroke}` }} /> Editiert
            </span>
            <span className="flex items-center gap-1">
              <span className="w-3 h-3 rounded-sm" style={{ background: STATUS_COLORS.skipped.fill, border: `1px solid ${STATUS_COLORS.skipped.stroke}` }} /> Uebersprungen
            </span>
          </div>
        </div>

        {/* Right: Crops + Edit fields (1/3) */}
        <div className={`lg:w-1/3 border-l border-slate-200 p-4 space-y-4 ${isFullscreen ? 'overflow-y-auto h-full' : ''}`}>
          {currentEntry && (
            <>
              {/* Row crop */}
              {imageNatural.w > 0 && (
                <GTImageCrop
                  imageUrl={imageUrl}
                  bbox={currentEntry.bbox}
                  naturalWidth={imageNatural.w}
                  naturalHeight={imageNatural.h}
                  label="Gesamte Zeile"
                />
              )}

              {/* Column crops */}
              {imageNatural.w > 0 && (
                <div className="grid grid-cols-3 gap-2">
                  {currentEntry.bbox_en.w > 0 && (
                    <GTImageCrop
                      imageUrl={imageUrl}
                      bbox={currentEntry.bbox_en}
                      naturalWidth={imageNatural.w}
                      naturalHeight={imageNatural.h}
                      maxWidth={120}
                      label="EN"
                    />
                  )}
                  {currentEntry.bbox_de.w > 0 && (
                    <GTImageCrop
                      imageUrl={imageUrl}
                      bbox={currentEntry.bbox_de}
                      naturalWidth={imageNatural.w}
                      naturalHeight={imageNatural.h}
                      maxWidth={120}
                      label="DE"
                    />
                  )}
                  {currentEntry.bbox_ex.w > 0 && (
                    <GTImageCrop
                      imageUrl={imageUrl}
                      bbox={currentEntry.bbox_ex}
                      naturalWidth={imageNatural.w}
                      naturalHeight={imageNatural.h}
                      maxWidth={120}
                      label="EX"
                    />
                  )}
                </div>
              )}

              {/* Confidence badge */}
              <div className="flex items-center gap-2">
                <span className={`text-xs px-2 py-0.5 rounded-full font-medium ${
                  currentEntry.confidence >= 70 ? 'bg-green-100 text-green-700' :
                  currentEntry.confidence >= 40 ? 'bg-yellow-100 text-yellow-700' :
                  'bg-red-100 text-red-700'
                }`}>
                  Konfidenz: {currentEntry.confidence}%
                </span>
              </div>

              {/* Edit fields */}
              <div className="space-y-3">
                <div>
                  <label className="block text-xs font-medium text-slate-500 mb-1">English</label>
                  <input
                    ref={enInputRef}
                    type="text"
                    value={editEn}
                    onChange={e => setEditEn(e.target.value)}
                    className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500 focus:border-teal-500"
                  />
                </div>
                <div>
                  <label className="block text-xs font-medium text-slate-500 mb-1">Deutsch</label>
                  <input
                    type="text"
                    value={editDe}
                    onChange={e => setEditDe(e.target.value)}
                    className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500 focus:border-teal-500"
                  />
                </div>
                <div>
                  <label className="block text-xs font-medium text-slate-500 mb-1">Beispiel</label>
                  <input
                    type="text"
                    value={editEx}
                    onChange={e => setEditEx(e.target.value)}
                    className="w-full px-3 py-2 border border-slate-300 rounded-lg text-sm focus:ring-2 focus:ring-teal-500 focus:border-teal-500"
                  />
                </div>
              </div>

              {/* Action buttons */}
              <div className="flex gap-2">
                <button
                  onClick={confirmEntry}
                  className="flex-1 px-4 py-2.5 bg-green-600 text-white rounded-lg font-medium hover:bg-green-700 text-sm"
                  title="Enter"
                >
                  OK (Enter)
                </button>
                <button
                  onClick={skipEntry}
                  className="flex-1 px-4 py-2.5 bg-slate-200 text-slate-700 rounded-lg font-medium hover:bg-slate-300 text-sm"
                  title="Tab"
                >
                  Skip (Tab)
                </button>
              </div>

              {/* Navigation */}
              <div className="flex items-center justify-between">
                <button
                  onClick={() => goTo(currentIndex - 1)}
                  disabled={currentIndex === 0}
                  className="px-3 py-1.5 bg-slate-100 rounded-lg text-sm text-slate-600 hover:bg-slate-200 disabled:opacity-30"
                >
                  &larr; Zurueck
                </button>
                <span className="text-sm text-slate-500 font-medium">
                  {currentIndex + 1} / {entries.length}
                </span>
                <button
                  onClick={() => goTo(currentIndex + 1)}
                  disabled={currentIndex === entries.length - 1}
                  className="px-3 py-1.5 bg-slate-100 rounded-lg text-sm text-slate-600 hover:bg-slate-200 disabled:opacity-30"
                >
                  Weiter &rarr;
                </button>
              </div>

              {/* Progress stats */}
              <div className="text-xs text-slate-400 text-center">
                {confirmedCount} bestaetigt &middot; {editedCount} editiert &middot; {skippedCount} uebersprungen &middot; {progress}%
              </div>

              {/* Keyboard hints */}
              <div className="text-xs text-slate-400 text-center border-t border-slate-100 pt-2">
                Enter = Bestaetigen &middot; Tab = Ueberspringen &middot; &larr;&rarr; = Navigieren{isFullscreen ? ' \u00B7 Esc = Vollbild verlassen' : ''}
              </div>
            </>
          )}
        </div>
      </div>

      {error && (
        <div className="mx-4 mb-4 p-3 bg-red-50 border border-red-200 rounded-lg text-red-700 text-sm">{error}</div>
      )}
    </div>
  )
}
