'use client'

/**
 * OCR Comparison Tool
 *
 * Zeigt Original-PDF neben den Extraktionsergebnissen von verschiedenen OCR-Methoden.
 * Ermoeglicht direkten visuellen Vergleich mit voller Breite.
 * Bietet Session-Historie fuer Verbesserungsvergleiche.
 */

import { useState, useEffect, useCallback, useMemo } from 'react'
import { PagePurpose } from '@/components/common/PagePurpose'
import { AIToolsSidebarResponsive } from '@/components/ai/AIToolsSidebar'
import { QRCodeUpload, UploadedFile } from '@/components/QRCodeUpload'
import { GridOverlay, GridStats, GridLegend, CellCorrectionDialog, BlockReviewPanel, BlockReviewSummary, getCellBlockNumber } from '@/components/ocr'
import type { GridData, GridCell, BlockReviewData, BlockStatus } from '@/components/ocr'

interface VocabEntry {
  english: string
  german: string
  example?: string
}

interface MethodResult {
  name: string
  model: string
  duration_seconds: number
  vocabulary_count: number
  vocabulary: VocabEntry[]
  confidence: number
  error?: string
  success: boolean
}

interface ComparisonResult {
  session_id: string
  page_number: number
  methods: Record<string, MethodResult>
  comparison: {
    found_by_all_methods: Array<{ english: string; german: string; methods: string[] }>
    found_by_some_methods: Array<{ english: string; german: string; methods: string[] }>
    total_unique_vocabulary: number
    agreement_rate: number
  }
  recommendation: {
    best_method: string
    reason: string
  }
}

interface SessionInfo {
  id: string
  name: string
  created_at: string
  page_count?: number
}

// OCR-Methoden Konfiguration
const OCR_METHODS = {
  local_llm: {
    id: 'local_llm',
    name: 'Loesung A: Lokales 32B LLM',
    shortName: 'A: Local LLM',
    model: 'qwen2.5:32b extern',
    color: 'slate',
    description: 'Externes 32B LLM',
    enabled: true,
  },
  vision_llm: {
    id: 'vision_llm',
    name: 'Loesung B: Vision LLM',
    shortName: 'B: Vision LLM',
    model: 'qwen2.5vl:32b',
    color: 'blue',
    description: 'Direkte Bild-zu-Text Extraktion',
    enabled: true,
  },
  paddleocr: {
    id: 'paddleocr',
    name: 'Loesung C: PaddleOCR',
    shortName: 'C: PaddleOCR',
    model: 'paddleocr (x86)',
    color: 'red',
    description: 'Aktuell deaktiviert (Rosetta)',
    enabled: false,
  },
  tesseract: {
    id: 'tesseract',
    name: 'Loesung D: Tesseract',
    shortName: 'D: Tesseract',
    model: 'tesseract + qwen2.5:14b',
    color: 'purple',
    description: 'ARM64-nativ, Standard',
    enabled: true,
  },
}

export default function OCRComparePage() {
  // Session State
  const [sessionId, setSessionId] = useState<string | null>(null)
  const [pageCount, setPageCount] = useState(0)
  const [selectedPage, setSelectedPage] = useState(0)
  const [thumbnails, setThumbnails] = useState<string[]>([])
  const [loadingThumbnails, setLoadingThumbnails] = useState(false)

  // Session History
  const [sessions, setSessions] = useState<SessionInfo[]>([])
  const [loadingSessions, setLoadingSessions] = useState(false)
  const [showHistory, setShowHistory] = useState(false)

  // Comparison State
  const [comparing, setComparing] = useState(false)
  const [result, setResult] = useState<ComparisonResult | null>(null)
  const [error, setError] = useState<string | null>(null)
  const [uploading, setUploading] = useState(false)

  // Method Selection
  const [selectedMethods, setSelectedMethods] = useState<string[]>(['vision_llm', 'tesseract'])

  // QR Upload State
  const [showQRModal, setShowQRModal] = useState(false)
  const [qrUploadSessionId, setQrUploadSessionId] = useState('')
  const [mobileUploadedFiles, setMobileUploadedFiles] = useState<UploadedFile[]>([])

  // View Mode State
  const [isFullscreen, setIsFullscreen] = useState(false)
  const [expandedMethod, setExpandedMethod] = useState<string | null>(null) // For single document view
  const [visibleMethods, setVisibleMethods] = useState<string[]>([]) // For custom multi-column view

  // Grid Detection State
  const [gridData, setGridData] = useState<GridData | null>(null)
  const [analyzingGrid, setAnalyzingGrid] = useState(false)
  const [showGridOverlay, setShowGridOverlay] = useState(true)
  const [selectedCell, setSelectedCell] = useState<GridCell | null>(null)
  const [showCellDialog, setShowCellDialog] = useState(false)

  // Block Review State
  const [blockReviewMode, setBlockReviewMode] = useState(false)
  const [currentBlockNumber, setCurrentBlockNumber] = useState(1)
  const [blockReviewData, setBlockReviewData] = useState<Record<number, BlockReviewData>>({})

  // Export State
  const [isExporting, setIsExporting] = useState(false)
  const [exportSuccess, setExportSuccess] = useState(false)

  const KLAUSUR_API = '/klausur-api'

  // Load session history
  const loadSessions = useCallback(async () => {
    setLoadingSessions(true)
    try {
      const res = await fetch(`${KLAUSUR_API}/api/v1/vocab/sessions`)
      if (res.ok) {
        const data = await res.json()
        // Filter to only show OCR Vergleich sessions and sort by date
        const ocrSessions = (data.sessions || data || [])
          .filter((s: SessionInfo) => s.name?.includes('OCR Vergleich'))
          .sort((a: SessionInfo, b: SessionInfo) =>
            new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
          )
          .slice(0, 20) // Limit to 20 most recent
        setSessions(ocrSessions)
      }
    } catch (e) {
      console.error('Failed to load sessions:', e)
    } finally {
      setLoadingSessions(false)
    }
  }, [])

  // Initialize and restore session
  useEffect(() => {
    loadSessions()

    let sid = localStorage.getItem('ocr-compare-upload-session')
    if (!sid) {
      sid = `ocr-compare-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`
      localStorage.setItem('ocr-compare-upload-session', sid)
    }
    setQrUploadSessionId(sid)

    // Restore last active session if available
    const lastSessionId = localStorage.getItem('ocr-compare-active-session')
    if (lastSessionId) {
      // Load the session data
      fetch(`${KLAUSUR_API}/api/v1/vocab/sessions/${lastSessionId}`)
        .then(res => {
          if (res.ok) return res.json()
          throw new Error('Session not found')
        })
        .then(data => {
          setSessionId(lastSessionId)
          setPageCount(data.page_count || 1)
          setSelectedPage(0)
          loadAllThumbnails(lastSessionId, data.page_count || 1)
        })
        .catch(() => {
          // Session no longer exists, clear localStorage
          localStorage.removeItem('ocr-compare-active-session')
        })
    }
  }, [loadSessions])

  // ESC key to exit fullscreen
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        if (expandedMethod) {
          setExpandedMethod(null)
        } else if (isFullscreen) {
          setIsFullscreen(false)
        }
      }
    }
    window.addEventListener('keydown', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [isFullscreen, expandedMethod])

  // Load a session from history
  const loadSession = async (session: SessionInfo) => {
    setSessionId(session.id)
    localStorage.setItem('ocr-compare-active-session', session.id)
    setResult(null)
    setThumbnails([])

    try {
      // Get session details
      const res = await fetch(`${KLAUSUR_API}/api/v1/vocab/sessions/${session.id}`)
      if (res.ok) {
        const data = await res.json()
        setPageCount(data.page_count || 1)
        setSelectedPage(0)

        // Load thumbnails
        await loadAllThumbnails(session.id, data.page_count || 1)
      }
    } catch (e) {
      setError('Session konnte nicht geladen werden')
    }
  }

  // Handle mobile file upload
  const handleMobileFile = useCallback(async (file: UploadedFile) => {
    if (!file.dataUrl) return

    setUploading(true)
    setError(null)
    setResult(null)
    setThumbnails([])

    try {
      // Create session
      const sessionRes = await fetch(`${KLAUSUR_API}/api/v1/vocab/sessions`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: `OCR Vergleich - ${file.name}` })
      })

      if (!sessionRes.ok) throw new Error('Session konnte nicht erstellt werden')
      const sessionData = await sessionRes.json()
      setSessionId(sessionData.id)
      localStorage.setItem('ocr-compare-active-session', sessionData.id)

      // Convert dataUrl to blob and upload
      const response = await fetch(file.dataUrl)
      const blob = await response.blob()

      const formData = new FormData()
      formData.append('file', blob, file.name)

      const uploadRes = await fetch(
        `${KLAUSUR_API}/api/v1/vocab/sessions/${sessionData.id}/upload-pdf-info`,
        { method: 'POST', body: formData }
      )

      if (!uploadRes.ok) throw new Error('PDF Upload fehlgeschlagen')
      const uploadData = await uploadRes.json()
      setPageCount(uploadData.page_count || 1)
      setSelectedPage(0)

      // Load thumbnails
      await loadAllThumbnails(sessionData.id, uploadData.page_count || 1)

      // Refresh session list
      loadSessions()

    } catch (err) {
      setError(err instanceof Error ? err.message : 'Upload fehlgeschlagen')
    } finally {
      setUploading(false)
    }
  }, [loadSessions])

  // Watch for new mobile files
  useEffect(() => {
    if (mobileUploadedFiles.length > 0) {
      const latestFile = mobileUploadedFiles[mobileUploadedFiles.length - 1]
      handleMobileFile(latestFile)
      setShowQRModal(false)
    }
  }, [mobileUploadedFiles, handleMobileFile])

  const handleFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (!file) return

    setUploading(true)
    setError(null)
    setResult(null)
    setThumbnails([])

    try {
      // Create session
      const sessionRes = await fetch(`${KLAUSUR_API}/api/v1/vocab/sessions`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: `OCR Vergleich - ${file.name}` })
      })

      if (!sessionRes.ok) throw new Error('Session konnte nicht erstellt werden')
      const sessionData = await sessionRes.json()
      setSessionId(sessionData.id)
      localStorage.setItem('ocr-compare-active-session', sessionData.id)

      // Upload PDF
      const formData = new FormData()
      formData.append('file', file)

      const uploadRes = await fetch(
        `${KLAUSUR_API}/api/v1/vocab/sessions/${sessionData.id}/upload-pdf-info`,
        { method: 'POST', body: formData }
      )

      if (!uploadRes.ok) throw new Error('PDF Upload fehlgeschlagen')
      const uploadData = await uploadRes.json()
      setPageCount(uploadData.page_count || 1)
      setSelectedPage(0)

      // Load all thumbnails
      await loadAllThumbnails(sessionData.id, uploadData.page_count || 1)

      // Refresh session list
      loadSessions()

    } catch (err) {
      setError(err instanceof Error ? err.message : 'Upload fehlgeschlagen')
    } finally {
      setUploading(false)
    }
  }

  const loadAllThumbnails = async (sid: string, count: number) => {
    setLoadingThumbnails(true)
    const thumbs: string[] = []

    for (let i = 0; i < count; i++) {
      try {
        const res = await fetch(`${KLAUSUR_API}/api/v1/vocab/sessions/${sid}/pdf-thumbnail/${i}?hires=true`)
        if (res.ok) {
          const blob = await res.blob()
          thumbs.push(URL.createObjectURL(blob))
        } else {
          thumbs.push('')
        }
      } catch {
        thumbs.push('')
      }
    }

    setThumbnails(thumbs)
    setLoadingThumbnails(false)
  }

  const toggleMethod = (methodId: string) => {
    setSelectedMethods(prev =>
      prev.includes(methodId)
        ? prev.filter(m => m !== methodId)
        : [...prev, methodId]
    )
  }

  const runComparison = async () => {
    if (!sessionId || selectedMethods.length === 0) return

    setComparing(true)
    setError(null)

    try {
      const res = await fetch(
        `${KLAUSUR_API}/api/v1/vocab/sessions/${sessionId}/compare-ocr/${selectedPage}`,
        { method: 'POST' }
      )

      if (!res.ok) throw new Error(`Vergleich fehlgeschlagen: ${res.status}`)
      const data = await res.json()
      setResult(data)

    } catch (err) {
      setError(err instanceof Error ? err.message : 'Vergleich fehlgeschlagen')
    } finally {
      setComparing(false)
    }
  }

  // Grid Analysis
  const analyzeGrid = async () => {
    if (!sessionId) return

    setAnalyzingGrid(true)
    setError(null)

    try {
      const res = await fetch(
        `${KLAUSUR_API}/api/v1/vocab/sessions/${sessionId}/analyze-grid/${selectedPage}`,
        { method: 'POST' }
      )

      if (!res.ok) throw new Error(`Grid-Analyse fehlgeschlagen: ${res.status}`)
      const data = await res.json()

      if (data.success && data.grid) {
        setGridData(data.grid)
      } else {
        setError(data.error || 'Grid-Erkennung fehlgeschlagen')
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Grid-Analyse fehlgeschlagen')
    } finally {
      setAnalyzingGrid(false)
    }
  }

  // Handle cell click for correction
  const handleCellClick = useCallback((cell: GridCell) => {
    setSelectedCell(cell)
    setShowCellDialog(true)
  }, [])

  // Handle cell save
  const handleCellSave = useCallback((text: string) => {
    if (!gridData || !selectedCell) return

    // Update local grid data
    const updatedCells = gridData.cells.map(row =>
      row.map(cell =>
        cell.row === selectedCell.row && cell.col === selectedCell.col
          ? { ...cell, text, status: 'manual' as const, confidence: 1.0 }
          : cell
      )
    )

    // Recalculate stats
    const recognized = updatedCells.flat().filter(c => c.status === 'recognized').length
    const manual = updatedCells.flat().filter(c => c.status === 'manual').length
    const problematic = updatedCells.flat().filter(c => c.status === 'problematic').length
    const total = updatedCells.flat().length

    setGridData({
      ...gridData,
      cells: updatedCells,
      stats: {
        ...gridData.stats,
        recognized,
        manual,
        problematic,
        empty: total - recognized - manual - problematic,
        coverage: (recognized + manual) / total
      }
    })

    setShowCellDialog(false)
    setSelectedCell(null)
  }, [gridData, selectedCell])

  // Block Review Handlers
  const handleBlockApprove = useCallback((blockNumber: number, methodId: string, text: string) => {
    if (!gridData) return

    const cell = gridData.cells.flat().find(c => getCellBlockNumber(c, gridData) === blockNumber)
    if (!cell) return

    setBlockReviewData(prev => ({
      ...prev,
      [blockNumber]: {
        blockNumber,
        cell,
        methodResults: [],
        status: 'approved' as BlockStatus,
        correctedText: text,
        approvedMethodId: methodId,
      }
    }))
  }, [gridData])

  const handleBlockCorrect = useCallback((blockNumber: number, correctedText: string) => {
    if (!gridData) return

    const cell = gridData.cells.flat().find(c => getCellBlockNumber(c, gridData) === blockNumber)
    if (!cell) return

    setBlockReviewData(prev => ({
      ...prev,
      [blockNumber]: {
        blockNumber,
        cell,
        methodResults: [],
        status: 'corrected' as BlockStatus,
        correctedText,
      }
    }))
  }, [gridData])

  const handleBlockSkip = useCallback((blockNumber: number) => {
    if (!gridData) return

    const cell = gridData.cells.flat().find(c => getCellBlockNumber(c, gridData) === blockNumber)
    if (!cell) return

    setBlockReviewData(prev => ({
      ...prev,
      [blockNumber]: {
        blockNumber,
        cell,
        methodResults: [],
        status: 'skipped' as BlockStatus,
      }
    }))
  }, [gridData])

  // Start block review mode
  const startBlockReview = useCallback(() => {
    if (!gridData) return

    // Find first non-empty block
    const firstBlock = gridData.cells.flat().find(c => c.status !== 'empty')
    if (firstBlock) {
      setCurrentBlockNumber(getCellBlockNumber(firstBlock, gridData))
      setBlockReviewMode(true)
    }
  }, [gridData])

  // Export to Worksheet Editor
  const handleExportToEditor = useCallback(async () => {
    if (!gridData || !sessionId) return

    setIsExporting(true)
    setExportSuccess(false)

    try {
      // Convert grid cells (percent coordinates) to mm for A4
      const A4_WIDTH_MM = 210
      const A4_HEIGHT_MM = 297

      const words = gridData.cells.flat()
        .filter(cell => cell.status !== 'empty' && cell.text)
        .map(cell => ({
          text: cell.text,
          x_mm: (cell.x / 100) * A4_WIDTH_MM,
          y_mm: (cell.y / 100) * A4_HEIGHT_MM,
          width_mm: (cell.width / 100) * A4_WIDTH_MM,
          height_mm: (cell.height / 100) * A4_HEIGHT_MM,
          column_type: cell.column_type || 'unknown',
          logical_row: cell.row,
          confidence: cell.confidence,
        }))

      const detectedColumns = gridData.column_types.map((type, idx) => ({
        column_type: type,
        x_start_mm: (gridData.column_boundaries[idx] / 100) * A4_WIDTH_MM,
        x_end_mm: (gridData.column_boundaries[idx + 1] / 100) * A4_WIDTH_MM,
      }))

      const exportData = {
        version: '1.0',
        source: 'ocr-compare',
        exported_at: new Date().toISOString(),
        session_id: sessionId,
        page_number: selectedPage + 1,
        page_dimensions: {
          width_mm: A4_WIDTH_MM,
          height_mm: A4_HEIGHT_MM,
          format: 'A4',
        },
        words,
        detected_columns: detectedColumns,
      }

      const res = await fetch(
        `${KLAUSUR_API}/api/v1/vocab/sessions/${sessionId}/ocr-export/${selectedPage + 1}`,
        {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(exportData),
        }
      )

      if (res.ok) {
        setExportSuccess(true)
        setTimeout(() => setExportSuccess(false), 3000)
      }
    } catch (e) {
      console.error('Export failed:', e)
    } finally {
      setIsExporting(false)
    }
  }, [gridData, sessionId, selectedPage, KLAUSUR_API])

  // Count non-empty blocks
  const nonEmptyBlockCount = useMemo(() => {
    if (!gridData) return 0
    return gridData.cells.flat().filter(c => c.status !== 'empty').length
  }, [gridData])

  const VocabList = ({ vocab, highlight }: { vocab: VocabEntry[]; highlight?: Set<string> }) => (
    <div className="space-y-1 max-h-[500px] overflow-y-auto">
      {vocab.map((v, idx) => {
        const key = `${v.english}|${v.german}`
        const isUnique = highlight?.has(key)
        return (
          <div
            key={idx}
            className={`p-2 rounded text-sm ${
              isUnique ? 'bg-yellow-100 border border-yellow-300' : 'bg-white border border-slate-200'
            }`}
          >
            <div className="font-medium text-slate-900">{v.english}</div>
            <div className="text-slate-600">{v.german}</div>
            {v.example && (
              <div className="text-xs text-slate-500 mt-1 italic">{v.example}</div>
            )}
          </div>
        )
      })}
    </div>
  )

  const getUniqueVocab = (methodKey: string): Set<string> => {
    if (!result?.comparison?.found_by_some_methods) return new Set()
    const unique = new Set<string>()
    result.comparison.found_by_some_methods.forEach(v => {
      if (v.methods.includes(methodKey) && v.methods.length === 1) {
        unique.add(`${v.english}|${v.german}`)
      }
    })
    return unique
  }

  const getMethodColor = (color: string, type: 'bg' | 'border' | 'text') => {
    const colors: Record<string, Record<string, string>> = {
      slate: { bg: 'bg-slate-50', border: 'border-slate-300', text: 'text-slate-700' },
      blue: { bg: 'bg-blue-50', border: 'border-blue-300', text: 'text-blue-700' },
      red: { bg: 'bg-red-50', border: 'border-red-300', text: 'text-red-700' },
      purple: { bg: 'bg-purple-50', border: 'border-purple-300', text: 'text-purple-700' },
    }
    return colors[color]?.[type] || colors.slate[type]
  }

  // Anzahl der ausgewaehlten Methoden + 1 fuer das Original
  const columnCount = selectedMethods.length + 1

  return (
    <div className="min-h-screen">
      <PagePurpose
        title="OCR Vergleich"
        purpose="Visueller Vergleich verschiedener OCR-Methoden. Laden Sie ein PDF hoch und sehen Sie das Original neben den Extraktionsergebnissen. Nutzen Sie die Session-Historie um Verbesserungen zu vergleichen."
        audience={['Entwickler', 'Lehrkraefte', 'QA']}
        architecture={{
          services: ['klausur-service', 'Ollama (qwen2.5vl:32b)', 'Tesseract OCR'],
          databases: ['PostgreSQL (Sessions)'],
        }}
        relatedPages={[
          { name: 'LLM Vergleich', href: '/ai/llm-compare', description: 'KI-Provider vergleichen' },
          { name: 'OCR-Labeling', href: '/ai/ocr-labeling', description: 'Ground Truth erstellen' },
        ]}
        collapsible={true}
        defaultCollapsed={true}
      />

      {/* KI-Werkzeuge Sidebar */}
      <AIToolsSidebarResponsive currentTool="ocr-compare" />

      <div className="grid grid-cols-1 lg:grid-cols-4 gap-6">
        {/* Left Sidebar: Upload & History */}
        <div className="lg:col-span-1 space-y-4">
          {/* Upload Section */}
          <div className="bg-white rounded-xl border border-slate-200 p-4">
            <h2 className="font-semibold text-slate-900 mb-3">PDF hochladen</h2>

            <input
              type="file"
              accept=".pdf"
              onChange={handleFileUpload}
              disabled={uploading}
              className="w-full text-sm text-slate-500 file:mr-4 file:py-2 file:px-4 file:rounded-lg file:border-0 file:text-sm file:font-medium file:bg-teal-50 file:text-teal-700 hover:file:bg-teal-100 disabled:opacity-50 mb-3"
            />

            <button
              onClick={() => setShowQRModal(true)}
              className="w-full px-4 py-2 bg-purple-100 text-purple-700 rounded-lg text-sm font-medium hover:bg-purple-200 flex items-center justify-center gap-2"
            >
              <span>📱</span>
              Mit Handy hochladen
            </button>

            {uploading && (
              <div className="mt-3 flex items-center gap-2 text-slate-600 text-sm">
                <svg className="animate-spin w-4 h-4" 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>
                Wird hochgeladen...
              </div>
            )}

            {error && (
              <div className="mt-3 p-2 bg-red-50 border border-red-200 rounded-lg text-red-700 text-xs">
                {error}
              </div>
            )}
          </div>

          {/* Session History Panel */}
          <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
            <button
              onClick={() => setShowHistory(!showHistory)}
              className="w-full px-4 py-3 flex items-center justify-between hover:bg-slate-50"
            >
              <span className="font-semibold text-slate-900">
                Session-Historie ({sessions.length})
              </span>
              <svg
                className={`w-5 h-5 transition-transform ${showHistory ? 'rotate-180' : ''}`}
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 9l-7 7-7-7" />
              </svg>
            </button>

            {showHistory && (
              <div className="border-t border-slate-200 max-h-96 overflow-y-auto">
                {loadingSessions ? (
                  <div className="p-4 text-center text-slate-500 text-sm">
                    <svg className="animate-spin w-5 h-5 mx-auto mb-2" 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>
                    Lade Sessions...
                  </div>
                ) : sessions.length === 0 ? (
                  <div className="p-4 text-center text-slate-500 text-sm">
                    Keine Sessions vorhanden
                  </div>
                ) : (
                  sessions.map(session => (
                    <button
                      key={session.id}
                      onClick={() => loadSession(session)}
                      className={`w-full px-4 py-3 text-left hover:bg-slate-50 border-b border-slate-100 last:border-0 transition-colors ${
                        sessionId === session.id ? 'bg-teal-50' : ''
                      }`}
                    >
                      <div className="text-sm text-slate-700 truncate">
                        {session.name?.replace('OCR Vergleich - ', '') || 'Unbenannt'}
                      </div>
                      <div className="text-xs text-slate-400 mt-0.5">
                        {new Date(session.created_at).toLocaleString('de-DE', {
                          day: '2-digit',
                          month: '2-digit',
                          year: '2-digit',
                          hour: '2-digit',
                          minute: '2-digit'
                        })}
                      </div>
                      {sessionId === session.id && (
                        <span className="inline-block mt-1 px-2 py-0.5 bg-teal-200 text-teal-800 text-xs rounded">
                          Aktiv
                        </span>
                      )}
                    </button>
                  ))
                )}
              </div>
            )}
          </div>

          {/* Method Selection */}
          {sessionId && pageCount > 0 && (
            <div className="bg-white rounded-xl border border-slate-200 p-4">
              <h3 className="font-semibold text-slate-900 mb-3 text-sm">OCR-Methoden</h3>

              <div className="space-y-2">
                {Object.values(OCR_METHODS).map(method => (
                  <label
                    key={method.id}
                    className={`flex items-center gap-2 p-2 rounded-lg border cursor-pointer transition-colors text-sm ${
                      !method.enabled ? 'opacity-50 cursor-not-allowed' : ''
                    } ${
                      selectedMethods.includes(method.id)
                        ? `border-2 ${getMethodColor(method.color, 'border')} ${getMethodColor(method.color, 'bg')}`
                        : 'border-slate-200 hover:bg-slate-50'
                    }`}
                  >
                    <input
                      type="checkbox"
                      checked={selectedMethods.includes(method.id)}
                      onChange={() => method.enabled && toggleMethod(method.id)}
                      disabled={!method.enabled}
                      className="rounded"
                    />
                    <div className="flex-1 min-w-0">
                      <div className="font-medium text-slate-900">{method.shortName}</div>
                      <div className="text-xs text-slate-500 truncate">{method.model}</div>
                    </div>
                  </label>
                ))}
              </div>

              <div className="mt-4 space-y-2">
                <button
                  onClick={runComparison}
                  disabled={comparing || selectedMethods.length === 0}
                  className="w-full px-4 py-2 bg-indigo-600 text-white rounded-lg font-medium hover:bg-indigo-700 disabled:opacity-50 disabled:cursor-not-allowed text-sm"
                >
                  {comparing ? (
                    <span className="flex items-center justify-center gap-2">
                      <svg className="animate-spin w-4 h-4" 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>
                      Vergleiche...
                    </span>
                  ) : (
                    'Vergleich starten'
                  )}
                </button>

                {/* Grid Analysis Button */}
                <button
                  onClick={analyzeGrid}
                  disabled={analyzingGrid}
                  className="w-full px-4 py-2 bg-teal-600 text-white rounded-lg font-medium hover:bg-teal-700 disabled:opacity-50 disabled:cursor-not-allowed text-sm"
                >
                  {analyzingGrid ? (
                    <span className="flex items-center justify-center gap-2">
                      <svg className="animate-spin w-4 h-4" 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>
                      Analysiere Grid...
                    </span>
                  ) : (
                    <span className="flex items-center justify-center gap-2">
                      <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 6h16M4 10h16M4 14h16M4 18h16" />
                      </svg>
                      Grid analysieren
                    </span>
                  )}
                </button>
              </div>

              {/* Grid Overlay Toggle */}
              {gridData && (
                <div className="mt-4 pt-4 border-t border-slate-200 space-y-3">
                  <label className="flex items-center gap-2 text-sm cursor-pointer">
                    <input
                      type="checkbox"
                      checked={showGridOverlay}
                      onChange={(e) => setShowGridOverlay(e.target.checked)}
                      className="rounded"
                    />
                    <span className="text-slate-700">Grid-Overlay anzeigen</span>
                  </label>

                  {/* Block Review Button */}
                  {result && nonEmptyBlockCount > 0 && (
                    <button
                      onClick={() => blockReviewMode ? setBlockReviewMode(false) : startBlockReview()}
                      className={`w-full px-4 py-2 rounded-lg font-medium text-sm transition-colors ${
                        blockReviewMode
                          ? 'bg-indigo-100 text-indigo-700 hover:bg-indigo-200'
                          : 'bg-indigo-600 text-white hover:bg-indigo-700'
                      }`}
                    >
                      {blockReviewMode ? (
                        <span className="flex items-center justify-center gap-2">
                          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                          </svg>
                          Block-Review beenden
                        </span>
                      ) : (
                        <span className="flex items-center justify-center gap-2">
                          <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
                          </svg>
                          Block-Review starten ({nonEmptyBlockCount} Blöcke)
                        </span>
                      )}
                    </button>
                  )}

                  {/* Export to Editor Button */}
                  <button
                    onClick={handleExportToEditor}
                    disabled={isExporting}
                    className={`w-full px-4 py-2 rounded-lg font-medium text-sm transition-colors ${
                      exportSuccess
                        ? 'bg-green-100 text-green-700'
                        : 'bg-green-600 text-white hover:bg-green-700'
                    }`}
                  >
                    <span className="flex items-center justify-center gap-2">
                      {isExporting ? (
                        <svg className="animate-spin w-4 h-4" 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>
                      ) : exportSuccess ? (
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                        </svg>
                      ) : (
                        <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
                        </svg>
                      )}
                      {exportSuccess ? 'Exportiert!' : 'Zum Editor exportieren'}
                    </span>
                  </button>
                </div>
              )}
            </div>
          )}

          {/* Grid Stats */}
          {gridData && (
            <div className="bg-white rounded-xl border border-slate-200 p-4">
              <h3 className="font-semibold text-slate-900 mb-3 text-sm">Grid-Erkennung</h3>
              <GridStats stats={gridData.stats} deskewAngle={gridData.deskew_angle} />
              <div className="mt-3">
                <GridLegend className="text-xs" />
              </div>
            </div>
          )}

          {/* Block Review Summary */}
          {blockReviewMode && gridData && Object.keys(blockReviewData).length > 0 && (
            <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
              <BlockReviewSummary
                reviewData={blockReviewData}
                totalBlocks={nonEmptyBlockCount}
                onBlockClick={(blockNumber) => setCurrentBlockNumber(blockNumber)}
              />
            </div>
          )}
        </div>

        {/* Main Content Area */}
        <div className="lg:col-span-3 space-y-4">
          {/* Page Thumbnails Grid */}
          {sessionId && pageCount > 0 && (
            <div className="bg-white rounded-xl border border-slate-200 p-4">
              <h3 className="font-semibold text-slate-900 mb-3">
                Seite auswaehlen ({pageCount} Seiten)
              </h3>

              {loadingThumbnails ? (
                <div className="flex items-center justify-center py-6">
                  <svg className="animate-spin w-8 h-8 text-teal-600" 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>
                  <span className="ml-3 text-slate-600">Lade Seitenvorschau...</span>
                </div>
              ) : (
                <div className="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 lg:grid-cols-10 gap-2">
                  {thumbnails.map((thumb, idx) => (
                    <button
                      key={idx}
                      onClick={() => {
                        setSelectedPage(idx)
                        setResult(null)
                        setGridData(null)  // Reset grid when changing page
                        setSelectedCell(null)
                      }}
                      className={`relative group rounded-lg overflow-hidden border-2 transition-all ${
                        selectedPage === idx
                          ? 'border-teal-500 ring-2 ring-teal-200'
                          : 'border-slate-200 hover:border-slate-300'
                      }`}
                    >
                      {thumb ? (
                        <img
                          src={thumb}
                          alt={`Seite ${idx + 1}`}
                          className="w-full aspect-[3/4] object-cover"
                        />
                      ) : (
                        <div className="w-full aspect-[3/4] bg-slate-100 flex items-center justify-center">
                          <span className="text-slate-400 text-xs">?</span>
                        </div>
                      )}
                      <div className={`absolute bottom-0 left-0 right-0 py-0.5 text-center text-xs font-medium ${
                        selectedPage === idx
                          ? 'bg-teal-600 text-white'
                          : 'bg-black/50 text-white'
                      }`}>
                        {idx + 1}
                      </div>
                    </button>
                  ))}
                </div>
              )}
            </div>
          )}

          {/* Full-Width Comparison View */}
          {(thumbnails[selectedPage] || result) && sessionId && (
            <div className={`bg-white rounded-xl border border-slate-200 p-4 ${
              isFullscreen ? 'fixed inset-0 z-50 overflow-auto m-0 rounded-none bg-slate-50' : ''
            }`}>
              {/* Header with Controls */}
              <div className="flex items-center justify-between mb-4">
                <h3 className="font-semibold text-slate-900">
                  Vergleich - Seite {selectedPage + 1}
                </h3>

                <div className="flex items-center gap-2">
                  {/* Layout Selector - only show after comparison */}
                  {result && (
                    <div className="flex items-center gap-1 bg-slate-100 rounded-lg p-1">
                      <span className="text-xs text-slate-500 px-2">Ansicht:</span>
                      {[1, 2, 3, 4].map(cols => (
                        <button
                          key={cols}
                          onClick={() => {
                            if (cols === 1) {
                              // Show selector for which single item to view
                              setExpandedMethod(null)
                              setVisibleMethods([])
                            } else {
                              setExpandedMethod(null)
                              // Auto-select first N methods
                              const methodsToShow = ['original', ...selectedMethods].slice(0, cols)
                              setVisibleMethods(methodsToShow)
                            }
                          }}
                          className={`w-8 h-8 flex items-center justify-center rounded text-sm font-medium transition-colors ${
                            (visibleMethods.length === cols || (cols === selectedMethods.length + 1 && visibleMethods.length === 0 && !expandedMethod))
                              ? 'bg-indigo-600 text-white'
                              : 'text-slate-600 hover:bg-slate-200'
                          }`}
                          title={`${cols} ${cols === 1 ? 'Spalte' : 'Spalten'}`}
                        >
                          {cols}
                        </button>
                      ))}
                      <button
                        onClick={() => {
                          setExpandedMethod(null)
                          setVisibleMethods([])
                        }}
                        className={`px-2 h-8 flex items-center justify-center rounded text-sm font-medium transition-colors ${
                          visibleMethods.length === 0 && !expandedMethod
                            ? 'bg-indigo-600 text-white'
                            : 'text-slate-600 hover:bg-slate-200'
                        }`}
                        title="Alle anzeigen"
                      >
                        Alle
                      </button>
                    </div>
                  )}

                  {/* Fullscreen Toggle */}
                  <button
                    onClick={() => setIsFullscreen(!isFullscreen)}
                    className="p-2 rounded-lg hover:bg-slate-100 transition-colors"
                    title={isFullscreen ? 'Vollbild beenden (Esc)' : 'Vollbild'}
                  >
                    {isFullscreen ? (
                      <svg className="w-5 h-5 text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                      </svg>
                    ) : (
                      <svg className="w-5 h-5 text-slate-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" />
                      </svg>
                    )}
                  </button>
                </div>
              </div>

              {/* Single Method Expanded View */}
              {expandedMethod && (
                <div className="mb-4">
                  <button
                    onClick={() => setExpandedMethod(null)}
                    className="mb-3 px-3 py-1.5 bg-slate-100 hover:bg-slate-200 rounded-lg text-sm text-slate-600 flex items-center gap-2"
                  >
                    <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
                    </svg>
                    Zurueck zur Uebersicht
                  </button>

                  {expandedMethod === 'original' ? (
                    <div className="bg-slate-50 rounded-xl border border-slate-200 overflow-hidden">
                      <div className="px-4 py-3 bg-slate-100 border-b border-slate-200">
                        <h4 className="font-semibold text-slate-900 text-lg">Original - Seite {selectedPage + 1}</h4>
                      </div>
                      <div className="p-4">
                        {thumbnails[selectedPage] ? (
                          gridData && showGridOverlay ? (
                            <GridOverlay
                              grid={gridData}
                              imageUrl={thumbnails[selectedPage]}
                              onCellClick={handleCellClick}
                              selectedCell={selectedCell}
                              showEmpty={false}
                              showNumbers={blockReviewMode}
                              showTextLabels={true}
                              highlightedBlockNumber={blockReviewMode ? currentBlockNumber : null}
                              className={`rounded-lg border border-slate-200 overflow-hidden ${isFullscreen ? 'max-h-[80vh] mx-auto' : 'w-full max-w-2xl mx-auto'}`}
                            />
                          ) : (
                            <img
                              src={thumbnails[selectedPage]}
                              alt={`Seite ${selectedPage + 1}`}
                              className={`rounded-lg border border-slate-200 ${isFullscreen ? 'max-h-[80vh] mx-auto' : 'w-full max-w-2xl mx-auto'}`}
                            />
                          )
                        ) : (
                          <div className="h-96 bg-slate-100 rounded-lg flex items-center justify-center text-slate-500">
                            Kein Bild verfuegbar
                          </div>
                        )}
                      </div>
                    </div>
                  ) : (
                    (() => {
                      const method = OCR_METHODS[expandedMethod as keyof typeof OCR_METHODS]
                      const methodResult = result?.methods?.[expandedMethod]
                      const isBest = result?.recommendation?.best_method === expandedMethod
                      return (
                        <div className={`rounded-xl border overflow-hidden ${isBest ? 'border-green-500 border-2' : 'border-slate-200'}`}>
                          <div className={`px-4 py-3 border-b flex items-center justify-between ${isBest ? 'bg-green-50 border-green-200' : getMethodColor(method.color, 'bg')}`}>
                            <div>
                              <h4 className="font-semibold text-slate-900 text-lg">{method.name}</h4>
                              <p className="text-sm text-slate-500">{method.model}</p>
                            </div>
                            {isBest && (
                              <span className="px-3 py-1.5 bg-green-200 text-green-800 text-sm font-medium rounded">
                                Beste Methode
                              </span>
                            )}
                          </div>
                          <div className="p-4">
                            {methodResult && (
                              <div className="max-w-4xl mx-auto">
                                <div className={`mb-4 p-4 rounded-lg ${getMethodColor(method.color, 'bg')}`}>
                                  <div className="grid grid-cols-3 gap-4 text-center">
                                    <div>
                                      <div className="text-2xl font-bold text-slate-900">{methodResult.duration_seconds}s</div>
                                      <div className={`text-sm ${getMethodColor(method.color, 'text')}`}>Dauer</div>
                                    </div>
                                    <div>
                                      <div className="text-2xl font-bold text-slate-900">{methodResult.vocabulary_count}</div>
                                      <div className={`text-sm ${getMethodColor(method.color, 'text')}`}>Vokabeln</div>
                                    </div>
                                    <div>
                                      <div className="text-2xl font-bold text-slate-900">{(methodResult.confidence * 100).toFixed(0)}%</div>
                                      <div className={`text-sm ${getMethodColor(method.color, 'text')}`}>Konfidenz</div>
                                    </div>
                                  </div>
                                </div>
                                {methodResult.vocabulary?.length > 0 && (
                                  <div className={`${isFullscreen ? 'max-h-[60vh]' : 'max-h-[600px]'} overflow-y-auto`}>
                                    <VocabList vocab={methodResult.vocabulary} highlight={getUniqueVocab(expandedMethod)} />
                                  </div>
                                )}
                              </div>
                            )}
                          </div>
                        </div>
                      )
                    })()
                  )}
                </div>
              )}

              {/* Grid View (Normal or Custom Selection) */}
              {!expandedMethod && (
                <div
                  className="grid gap-4"
                  style={{
                    gridTemplateColumns: `repeat(${
                      visibleMethods.length > 0 ? visibleMethods.length : columnCount
                    }, minmax(0, 1fr))`
                  }}
                >
                  {/* Original PDF Column */}
                  {(visibleMethods.length === 0 || visibleMethods.includes('original')) && (
                    <div
                      className="bg-slate-50 rounded-xl border border-slate-200 overflow-hidden cursor-pointer hover:border-slate-400 transition-colors group"
                      onClick={() => setExpandedMethod('original')}
                    >
                      <div className="px-4 py-3 bg-slate-100 border-b border-slate-200 flex items-center justify-between">
                        <div>
                          <h4 className="font-semibold text-slate-900">Original</h4>
                          <p className="text-xs text-slate-500">Seite {selectedPage + 1}</p>
                        </div>
                        <svg className="w-4 h-4 text-slate-400 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" />
                        </svg>
                      </div>
                      <div className="p-3">
                        {thumbnails[selectedPage] ? (
                          <div className="relative">
                            {/* Show Grid Overlay if available */}
                            {gridData && showGridOverlay ? (
                              <GridOverlay
                                grid={gridData}
                                imageUrl={thumbnails[selectedPage]}
                                onCellClick={handleCellClick}
                                selectedCell={selectedCell}
                                showEmpty={false}
                                showNumbers={blockReviewMode}
                                showTextLabels={!blockReviewMode}
                                highlightedBlockNumber={blockReviewMode ? currentBlockNumber : null}
                                className="rounded-lg border border-slate-200 overflow-hidden"
                              />
                            ) : (
                              <img
                                src={thumbnails[selectedPage]}
                                alt={`Seite ${selectedPage + 1}`}
                                className="w-full rounded-lg border border-slate-200"
                              />
                            )}
                          </div>
                        ) : (
                          <div className="h-64 bg-slate-100 rounded-lg flex items-center justify-center text-slate-500">
                            Kein Bild verfuegbar
                          </div>
                        )}
                      </div>
                    </div>
                  )}

                  {/* Method Result Columns */}
                  {selectedMethods
                    .filter(methodId => visibleMethods.length === 0 || visibleMethods.includes(methodId))
                    .map(methodId => {
                      const method = OCR_METHODS[methodId as keyof typeof OCR_METHODS]
                      const methodResult = result?.methods?.[methodId]
                      const isBest = result?.recommendation?.best_method === methodId

                      return (
                        <div
                          key={methodId}
                          className={`rounded-xl border overflow-hidden cursor-pointer hover:border-slate-400 transition-colors group ${
                            isBest ? 'border-green-500 border-2' : 'border-slate-200'
                          }`}
                          onClick={() => setExpandedMethod(methodId)}
                        >
                          <div className={`px-4 py-3 border-b flex items-center justify-between ${
                            isBest ? 'bg-green-50 border-green-200' : getMethodColor(method.color, 'bg')
                          }`}>
                            <div>
                              <h4 className="font-semibold text-slate-900">{method.shortName}</h4>
                              <p className="text-xs text-slate-500">{method.model}</p>
                            </div>
                            <div className="flex items-center gap-2">
                              {isBest && (
                                <span className="px-2 py-1 bg-green-200 text-green-800 text-xs font-medium rounded">
                                  Beste
                                </span>
                              )}
                              <svg className="w-4 h-4 text-slate-400 opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" />
                              </svg>
                            </div>
                          </div>
                          <div className="p-3">
                            {comparing && !methodResult && (
                              <div className="h-64 flex flex-col items-center justify-center text-slate-500">
                                <svg className="animate-spin w-8 h-8 mb-2" 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>
                                Extrahiere...
                              </div>
                            )}
                            {methodResult && (
                              <div>
                                <div className={`mb-3 p-2 rounded-lg text-sm ${getMethodColor(method.color, 'bg')}`}>
                                  <div className="flex justify-between">
                                    <span className={getMethodColor(method.color, 'text')}>Dauer:</span>
                                    <span className="font-medium">{methodResult.duration_seconds}s</span>
                                  </div>
                                  <div className="flex justify-between">
                                    <span className={getMethodColor(method.color, 'text')}>Vokabeln:</span>
                                    <span className="font-medium">{methodResult.vocabulary_count}</span>
                                  </div>
                                  {methodResult.error && (
                                    <div className="text-red-600 text-xs mt-1">{methodResult.error}</div>
                                  )}
                                </div>
                                {methodResult.vocabulary?.length > 0 && (
                                  <VocabList
                                    vocab={methodResult.vocabulary}
                                    highlight={getUniqueVocab(methodId)}
                                  />
                                )}
                              </div>
                            )}
                            {!comparing && !methodResult && (
                              <div className="h-64 bg-slate-50 rounded-lg flex items-center justify-center text-slate-500">
                                Noch keine Ergebnisse
                              </div>
                            )}
                          </div>
                        </div>
                      )
                    })}
                </div>
              )}

              {/* Method Selector Chips (for custom view) */}
              {result && visibleMethods.length > 0 && visibleMethods.length < selectedMethods.length + 1 && (
                <div className="mt-4 pt-4 border-t border-slate-200">
                  <div className="flex flex-wrap gap-2">
                    <span className="text-sm text-slate-500 mr-2">Methoden ein-/ausblenden:</span>
                    <button
                      onClick={() => setVisibleMethods(prev =>
                        prev.includes('original')
                          ? prev.filter(m => m !== 'original')
                          : [...prev, 'original']
                      )}
                      className={`px-3 py-1 rounded-full text-sm font-medium transition-colors ${
                        visibleMethods.includes('original')
                          ? 'bg-slate-600 text-white'
                          : 'bg-slate-100 text-slate-600 hover:bg-slate-200'
                      }`}
                    >
                      Original
                    </button>
                    {selectedMethods.map(methodId => {
                      const method = OCR_METHODS[methodId as keyof typeof OCR_METHODS]
                      return (
                        <button
                          key={methodId}
                          onClick={() => setVisibleMethods(prev =>
                            prev.includes(methodId)
                              ? prev.filter(m => m !== methodId)
                              : [...prev, methodId]
                          )}
                          className={`px-3 py-1 rounded-full text-sm font-medium transition-colors ${
                            visibleMethods.includes(methodId)
                              ? 'bg-indigo-600 text-white'
                              : 'bg-slate-100 text-slate-600 hover:bg-slate-200'
                          }`}
                        >
                          {method.shortName}
                        </button>
                      )
                    })}
                  </div>
                </div>
              )}

              {/* Block Review Panel */}
              {blockReviewMode && gridData && result && (
                <div className="mt-6 bg-white rounded-xl border-2 border-indigo-300 shadow-lg overflow-hidden">
                  <div className="bg-indigo-50 px-4 py-3 border-b border-indigo-200">
                    <h3 className="font-semibold text-indigo-900 flex items-center gap-2">
                      <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
                      </svg>
                      Block-Review
                    </h3>
                    <p className="text-sm text-indigo-600 mt-1">
                      Prüfen Sie jeden Block und wählen Sie die korrekte Erkennung oder korrigieren Sie manuell.
                    </p>
                  </div>
                  <BlockReviewPanel
                    grid={gridData}
                    methodResults={result.methods}
                    currentBlockNumber={currentBlockNumber}
                    onBlockChange={setCurrentBlockNumber}
                    onApprove={handleBlockApprove}
                    onCorrect={handleBlockCorrect}
                    onSkip={handleBlockSkip}
                    reviewData={blockReviewData}
                    className="h-[400px]"
                  />
                </div>
              )}
            </div>
          )}

          {/* Comparison Summary */}
          {result?.comparison && (
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">Vergleichszusammenfassung</h3>

              <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
                <div className="p-4 bg-slate-50 rounded-lg text-center">
                  <div className="text-2xl font-bold text-slate-900">
                    {result.comparison.total_unique_vocabulary}
                  </div>
                  <div className="text-sm text-slate-600">Gesamt eindeutig</div>
                </div>
                <div className="p-4 bg-green-50 rounded-lg text-center">
                  <div className="text-2xl font-bold text-green-700">
                    {result.comparison.found_by_all_methods?.length || 0}
                  </div>
                  <div className="text-sm text-green-600">Von allen erkannt</div>
                </div>
                <div className="p-4 bg-yellow-50 rounded-lg text-center">
                  <div className="text-2xl font-bold text-yellow-700">
                    {result.comparison.found_by_some_methods?.length || 0}
                  </div>
                  <div className="text-sm text-yellow-600">Unterschiede</div>
                </div>
                <div className="p-4 bg-blue-50 rounded-lg text-center">
                  <div className="text-2xl font-bold text-blue-700">
                    {(result.comparison.agreement_rate * 100).toFixed(0)}%
                  </div>
                  <div className="text-sm text-blue-600">Uebereinstimmung</div>
                </div>
              </div>

              {result.recommendation && (
                <div className="p-4 bg-green-50 border border-green-200 rounded-lg mb-4">
                  <div className="flex items-center gap-2">
                    <span className="text-green-600 font-medium">Empfehlung:</span>
                    <span className="font-semibold text-green-800">
                      {OCR_METHODS[result.recommendation.best_method as keyof typeof OCR_METHODS]?.name || result.recommendation.best_method}
                    </span>
                  </div>
                  <p className="text-sm text-green-700 mt-1">{result.recommendation.reason}</p>
                </div>
              )}

              {result.comparison.found_by_some_methods?.length > 0 && (
                <div>
                  <h4 className="font-medium text-slate-900 mb-2">
                    Unterschiede (gelb markiert):
                  </h4>
                  <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2">
                    {result.comparison.found_by_some_methods.map((v, idx) => (
                      <div key={idx} className="p-2 bg-yellow-50 border border-yellow-200 rounded text-sm">
                        <span className="font-medium">{v.english}</span> = {v.german}
                        <span className="ml-2 text-yellow-700 text-xs">
                          (nur: {v.methods.join(', ')})
                        </span>
                      </div>
                    ))}
                  </div>
                </div>
              )}
            </div>
          )}

          {/* Empty State */}
          {!sessionId && (
            <div className="bg-white rounded-xl border border-slate-200 p-12 text-center">
              <svg
                className="w-16 h-16 mx-auto text-slate-300 mb-4"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={1.5}
                  d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
                />
              </svg>
              <h3 className="text-lg font-medium text-slate-700 mb-2">PDF hochladen</h3>
              <p className="text-slate-500 max-w-md mx-auto">
                Laden Sie ein PDF hoch oder waehlen Sie eine Session aus der Historie, um OCR-Methoden zu vergleichen.
              </p>
            </div>
          )}
        </div>
      </div>

      {/* QR Code Upload Modal */}
      {showQRModal && (
        <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
          <div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={() => setShowQRModal(false)} />
          <div className="relative w-full max-w-md">
            <QRCodeUpload
              sessionId={qrUploadSessionId}
              onClose={() => setShowQRModal(false)}
              onFilesChanged={(files) => {
                setMobileUploadedFiles(files)
              }}
            />
          </div>
        </div>
      )}

      {/* Cell Correction Dialog */}
      {showCellDialog && selectedCell && sessionId && gridData && (
        <CellCorrectionDialog
          cell={selectedCell}
          columnType={gridData.column_types[selectedCell.col] as 'english' | 'german' | 'example' | 'unknown' || 'unknown'}
          sessionId={sessionId}
          pageNumber={selectedPage}
          onSave={handleCellSave}
          onClose={() => {
            setShowCellDialog(false)
            setSelectedCell(null)
          }}
        />
      )}
    </div>
  )
}
