'use client'

/**
 * Custom hook encapsulating all state and API logic for the OCR Labeling page.
 */

import { useState, useEffect, useCallback } from 'react'
import { API_BASE } from './constants'
import type { OCRSession, OCRItem, OCRStats } from './types'

export function useOcrLabeling() {
  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)

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

  // Fetch queue
  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 res = await fetch(url)
      if (res.ok) {
        const data = await res.json()
        setQueue(data)
        if (data.length > 0 && !currentItem) {
          setCurrentItem(data[0])
          setCurrentIndex(0)
          setCorrectedText(data[0].ocr_text || '')
          setLabelStartTime(Date.now())
        }
      }
    } catch (err) {
      console.error('Failed to fetch queue:', err)
    }
  }, [selectedSession, currentItem])

  // Fetch stats
  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 res = await fetch(url)
      if (res.ok) {
        const data = await res.json()
        setStats(data)
      }
    } catch (err) {
      console.error('Failed to fetch stats:', err)
    }
  }, [selectedSession])

  // Initial data load
  useEffect(() => {
    const loadData = async () => {
      setLoading(true)
      await Promise.all([fetchSessions(), fetchQueue(), fetchStats()])
      setLoading(false)
    }
    loadData()
  }, [fetchSessions, fetchQueue, fetchStats])

  // Refresh queue when session changes
  useEffect(() => {
    setCurrentItem(null)
    setCurrentIndex(0)
    fetchQueue()
    fetchStats()
  }, [selectedSession, fetchQueue, fetchStats])

  // Navigate to next item
  const goToNext = useCallback(() => {
    if (currentIndex < queue.length - 1) {
      const nextIndex = currentIndex + 1
      setCurrentIndex(nextIndex)
      setCurrentItem(queue[nextIndex])
      setCorrectedText(queue[nextIndex].ocr_text || '')
      setLabelStartTime(Date.now())
    } else {
      fetchQueue()
    }
  }, [currentIndex, queue, fetchQueue])

  // Navigate to previous item
  const goToPrev = useCallback(() => {
    if (currentIndex > 0) {
      const prevIndex = currentIndex - 1
      setCurrentIndex(prevIndex)
      setCurrentItem(queue[prevIndex])
      setCorrectedText(queue[prevIndex].ocr_text || '')
      setLabelStartTime(Date.now())
    }
  }, [currentIndex, queue])

  // Calculate label time
  const getLabelTime = useCallback((): number | undefined => {
    if (!labelStartTime) return undefined
    return Math.round((Date.now() - labelStartTime) / 1000)
  }, [labelStartTime])

  // Select a queue item by index
  const selectQueueItem = useCallback((idx: number) => {
    if (idx >= 0 && idx < queue.length) {
      setCurrentIndex(idx)
      setCurrentItem(queue[idx])
      setCorrectedText(queue[idx].ocr_text || '')
      setLabelStartTime(Date.now())
    }
  }, [queue])

  // Confirm item
  const confirmItem = useCallback(async () => {
    if (!currentItem) return

    try {
      const res = await fetch(`${API_BASE}/api/v1/ocr-label/confirm`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          item_id: currentItem.id,
          label_time_seconds: getLabelTime(),
        }),
      })

      if (res.ok) {
        setQueue(prev => prev.filter(item => item.id !== currentItem.id))
        goToNext()
        fetchStats()
      } else {
        setError('Bestaetigung fehlgeschlagen')
      }
    } catch {
      setError('Netzwerkfehler')
    }
  }, [currentItem, getLabelTime, goToNext, fetchStats])

  // Correct item
  const correctItem = useCallback(async () => {
    if (!currentItem || !correctedText.trim()) return

    try {
      const res = await fetch(`${API_BASE}/api/v1/ocr-label/correct`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          item_id: currentItem.id,
          ground_truth: correctedText.trim(),
          label_time_seconds: getLabelTime(),
        }),
      })

      if (res.ok) {
        setQueue(prev => prev.filter(item => item.id !== currentItem.id))
        goToNext()
        fetchStats()
      } else {
        setError('Korrektur fehlgeschlagen')
      }
    } catch {
      setError('Netzwerkfehler')
    }
  }, [currentItem, correctedText, getLabelTime, goToNext, fetchStats])

  // Skip item
  const skipItem = useCallback(async () => {
    if (!currentItem) return

    try {
      const res = await fetch(`${API_BASE}/api/v1/ocr-label/skip`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ item_id: currentItem.id }),
      })

      if (res.ok) {
        setQueue(prev => prev.filter(item => item.id !== currentItem.id))
        goToNext()
        fetchStats()
      } else {
        setError('Ueberspringen fehlgeschlagen')
      }
    } catch {
      setError('Netzwerkfehler')
    }
  }, [currentItem, goToNext, fetchStats])

  // Keyboard shortcuts
  useEffect(() => {
    const handleKeyDown = (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', handleKeyDown)
    return () => window.removeEventListener('keydown', handleKeyDown)
  }, [confirmItem, goToNext, goToPrev, skipItem])

  return {
    // State
    sessions,
    selectedSession,
    setSelectedSession,
    queue,
    currentItem,
    currentIndex,
    stats,
    loading,
    error,
    setError,
    correctedText,
    setCorrectedText,

    // Actions
    fetchSessions,
    fetchQueue,
    fetchStats,
    goToNext,
    goToPrev,
    selectQueueItem,
    confirmItem,
    correctItem,
    skipItem,
  }
}
