'use client'

/**
 * OCR Labeling Admin Page
 *
 * Labeling interface for handwriting training data collection.
 * DSGVO-konform: Alle Verarbeitung lokal auf Mac Mini (Ollama).
 */

import { useState, useEffect, useCallback } from 'react'
import AdminLayout from '@/components/admin/AdminLayout'
import type { OCRSession, OCRItem, OCRStats } from './types'
import { API_BASE, tabs } from './constants'
import type { TabId } from './constants'
import LabelingTab from './_components/LabelingTab'
import SessionsTab from './_components/SessionsTab'
import UploadTab from './_components/UploadTab'
import StatsTab from './_components/StatsTab'
import ExportTab from './_components/ExportTab'

export default function OCRLabelingPage() {
  const [activeTab, setActiveTab] = useState<TabId>('labeling')
  const [sessions, setSessions] = useState<OCRSession[]>([])
  const [selectedSession, setSelectedSession] = useState<string | null>(null)
  const [queue, setQueue] = useState<OCRItem[]>([])
  const [currentItem, setCurrentItem] = useState<OCRItem | null>(null)
  const [currentIndex, setCurrentIndex] = useState(0)
  const [stats, setStats] = useState<OCRStats | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [correctedText, setCorrectedText] = useState('')
  const [labelStartTime, setLabelStartTime] = useState<number | null>(null)

  const fetchSessions = useCallback(async () => {
    try { const r = await fetch(`${API_BASE}/api/v1/ocr-label/sessions`); if (r.ok) setSessions(await r.json()) }
    catch (e) { console.error('Failed to fetch sessions:', e) }
  }, [])

  const fetchQueue = useCallback(async () => {
    try {
      const url = selectedSession ? `${API_BASE}/api/v1/ocr-label/queue?session_id=${selectedSession}&limit=20` : `${API_BASE}/api/v1/ocr-label/queue?limit=20`
      const r = await fetch(url)
      if (r.ok) {
        const data = await r.json(); setQueue(data)
        if (data.length > 0 && !currentItem) { setCurrentItem(data[0]); setCurrentIndex(0); setCorrectedText(data[0].ocr_text || ''); setLabelStartTime(Date.now()) }
      }
    } catch (e) { console.error('Failed to fetch queue:', e) }
  }, [selectedSession, currentItem])

  const fetchStats = useCallback(async () => {
    try {
      const url = selectedSession ? `${API_BASE}/api/v1/ocr-label/stats?session_id=${selectedSession}` : `${API_BASE}/api/v1/ocr-label/stats`
      const r = await fetch(url); if (r.ok) setStats(await r.json())
    } catch (e) { console.error('Failed to fetch stats:', e) }
  }, [selectedSession])

  useEffect(() => { setLoading(true); Promise.all([fetchSessions(), fetchQueue(), fetchStats()]).then(() => setLoading(false)) }, [fetchSessions, fetchQueue, fetchStats])
  useEffect(() => { setCurrentItem(null); setCurrentIndex(0); fetchQueue(); fetchStats() }, [selectedSession, fetchQueue, fetchStats])

  const getLabelTime = () => labelStartTime ? Math.round((Date.now() - labelStartTime) / 1000) : undefined

  const setItem = (item: OCRItem, idx: number) => { setCurrentIndex(idx); setCurrentItem(item); setCorrectedText(item.ocr_text || ''); setLabelStartTime(Date.now()) }

  const goToNext = () => {
    if (currentIndex < queue.length - 1) setItem(queue[currentIndex + 1], currentIndex + 1)
    else fetchQueue()
  }
  const goToPrev = () => { if (currentIndex > 0) setItem(queue[currentIndex - 1], currentIndex - 1) }

  const postAction = async (endpoint: string, body: object) => {
    const r = await fetch(`${API_BASE}/api/v1/ocr-label/${endpoint}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) })
    if (r.ok) { setQueue(prev => prev.filter(i => i.id !== currentItem?.id)); goToNext(); fetchStats() }
    else setError(`${endpoint} fehlgeschlagen`)
  }

  const confirmItem = () => { if (currentItem) postAction('confirm', { item_id: currentItem.id, label_time_seconds: getLabelTime() }).catch(() => setError('Netzwerkfehler')) }
  const correctItem = () => { if (currentItem && correctedText.trim()) postAction('correct', { item_id: currentItem.id, ground_truth: correctedText.trim(), label_time_seconds: getLabelTime() }).catch(() => setError('Netzwerkfehler')) }
  const skipItem = () => { if (currentItem) postAction('skip', { item_id: currentItem.id }).catch(() => setError('Netzwerkfehler')) }

  useEffect(() => {
    const h = (e: KeyboardEvent) => {
      if (e.target instanceof HTMLTextAreaElement) return
      if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); confirmItem() }
      else if (e.key === 'ArrowRight') goToNext()
      else if (e.key === 'ArrowLeft') goToPrev()
      else if (e.key === 's' && !e.ctrlKey && !e.metaKey) skipItem()
    }
    window.addEventListener('keydown', h); return () => window.removeEventListener('keydown', h)
  }, [currentItem, correctedText])

  return (
    <AdminLayout title="OCR-Labeling" description="Handschrift-Training & Ground Truth Erfassung">
      {error && (
        <div className="fixed top-4 right-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded z-50">
          <span>{error}</span>
          <button onClick={() => setError(null)} className="ml-4">X</button>
        </div>
      )}

      <div className="mb-6 border-b border-slate-200">
        <nav className="flex space-x-4" aria-label="Tabs">
          {tabs.map((tab) => (
            <button key={tab.id} onClick={() => setActiveTab(tab.id)} className={`flex items-center gap-2 px-4 py-3 border-b-2 font-medium text-sm transition-colors ${activeTab === tab.id ? 'border-primary-500 text-primary-600' : 'border-transparent text-slate-500 hover:text-slate-700 hover:border-slate-300'}`}>
              {tab.icon}{tab.name}
            </button>
          ))}
        </nav>
      </div>

      {loading ? (
        <div className="flex items-center justify-center h-64"><div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600" /></div>
      ) : (
        <>
          {activeTab === 'labeling' && <LabelingTab queue={queue} currentItem={currentItem} currentIndex={currentIndex} correctedText={correctedText} setCorrectedText={setCorrectedText} onGoToPrev={goToPrev} onGoToNext={goToNext} onConfirm={confirmItem} onCorrect={correctItem} onSkip={skipItem} onSelectItem={setItem} />}
          {activeTab === 'sessions' && <SessionsTab sessions={sessions} selectedSession={selectedSession} setSelectedSession={setSelectedSession} onSessionCreated={fetchSessions} onError={setError} />}
          {activeTab === 'upload' && <UploadTab sessions={sessions} selectedSession={selectedSession} setSelectedSession={setSelectedSession} onUploadComplete={() => { fetchQueue(); fetchStats() }} onError={setError} />}
          {activeTab === 'stats' && <StatsTab stats={stats} />}
          {activeTab === 'export' && <ExportTab sessions={sessions} selectedSession={selectedSession} setSelectedSession={setSelectedSession} stats={stats} onError={setError} />}
        </>
      )}
    </AdminLayout>
  )
}
