'use client'

import { useCallback, useEffect, useState } from 'react'
import type { ColumnResult, ColumnGroundTruth, PageRegion, SubSession } from '@/app/(admin)/ai/ocr-kombi/types'
import { ColumnControls } from './ColumnControls'
import { ManualColumnEditor } from './ManualColumnEditor'
import type { ColumnTypeKey } from '@/app/(admin)/ai/ocr-kombi/types'

const KLAUSUR_API = '/klausur-api'

type ViewMode = 'normal' | 'ground-truth' | 'manual'

interface StepColumnDetectionProps {
  sessionId: string | null
  onNext: () => void
  onBoxSessionsCreated?: (subSessions: SubSession[]) => void
}

/** Convert PageRegion[] to divider percentages + column types for ManualColumnEditor */
function columnsToEditorState(
  columns: PageRegion[],
  imageWidth: number
): { dividers: number[]; columnTypes: ColumnTypeKey[] } {
  if (!columns.length || !imageWidth) return { dividers: [], columnTypes: [] }

  const sorted = [...columns].sort((a, b) => a.x - b.x)
  const dividers: number[] = []
  const columnTypes: ColumnTypeKey[] = sorted.map(c => c.type)

  for (let i = 1; i < sorted.length; i++) {
    const xPct = (sorted[i].x / imageWidth) * 100
    dividers.push(xPct)
  }

  return { dividers, columnTypes }
}

export function StepColumnDetection({ sessionId, onNext, onBoxSessionsCreated }: StepColumnDetectionProps) {
  const [columnResult, setColumnResult] = useState<ColumnResult | null>(null)
  const [detecting, setDetecting] = useState(false)
  const [error, setError] = useState<string | null>(null)
  const [viewMode, setViewMode] = useState<ViewMode>('normal')
  const [applying, setApplying] = useState(false)
  const [imageDimensions, setImageDimensions] = useState<{ width: number; height: number } | null>(null)
  const [savedGtColumns, setSavedGtColumns] = useState<PageRegion[] | null>(null)
  const [creatingBoxSessions, setCreatingBoxSessions] = useState(false)
  const [existingSubSessions, setExistingSubSessions] = useState<SubSession[] | null>(null)
  const [isSubSession, setIsSubSession] = useState(false)

  // Fetch session info (image dimensions) + check for cached column result
  useEffect(() => {
    if (!sessionId || imageDimensions) return

    const fetchSessionInfo = async () => {
      try {
        const infoRes = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}`)
        if (infoRes.ok) {
          const info = await infoRes.json()
          if (info.image_width && info.image_height) {
            setImageDimensions({ width: info.image_width, height: info.image_height })
          }
          const isSub = !!info.parent_session_id
          setIsSubSession(isSub)
          if (info.sub_sessions && info.sub_sessions.length > 0) {
            setExistingSubSessions(info.sub_sessions)
            onBoxSessionsCreated?.(info.sub_sessions)
          }
          if (info.column_result) {
            setColumnResult(info.column_result)
            // Sub-session with pseudo-column already set → auto-advance
            if (isSub) {
              onNext()
              return
            }
            return
          }
          // Sub-session without columns → auto-detect (creates pseudo-column)
          if (isSub) {
            const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/columns`, { method: 'POST' })
            if (res.ok) {
              const data: ColumnResult = await res.json()
              setColumnResult(data)
              onNext()
              return
            }
          }
        }
      } catch (e) {
        console.error('Failed to fetch session info:', e)
      }

      // No cached result - run auto-detection
      runAutoDetection()
    }

    fetchSessionInfo()
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sessionId])

  // Load saved GT if exists
  useEffect(() => {
    if (!sessionId) return
    const fetchGt = async () => {
      try {
        const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/ground-truth/columns`)
        if (res.ok) {
          const data = await res.json()
          const corrected = data.columns_gt?.corrected_columns
          if (corrected) setSavedGtColumns(corrected)
        }
      } catch {
        // No saved GT - that's fine
      }
    }
    fetchGt()
  }, [sessionId])

  const runAutoDetection = useCallback(async () => {
    if (!sessionId) return
    setDetecting(true)
    setError(null)
    try {
      const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/columns`, {
        method: 'POST',
      })
      if (!res.ok) {
        const err = await res.json().catch(() => ({ detail: res.statusText }))
        throw new Error(err.detail || 'Spaltenerkennung fehlgeschlagen')
      }
      const data: ColumnResult = await res.json()
      setColumnResult(data)
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Unbekannter Fehler')
    } finally {
      setDetecting(false)
    }
  }, [sessionId])

  const handleRerun = useCallback(() => {
    runAutoDetection()
  }, [runAutoDetection])

  const handleGroundTruth = useCallback(async (gt: ColumnGroundTruth) => {
    if (!sessionId) return
    try {
      await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/ground-truth/columns`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(gt),
      })
    } catch (e) {
      console.error('Ground truth save failed:', e)
    }
  }, [sessionId])

  const handleManualApply = useCallback(async (columns: PageRegion[]) => {
    if (!sessionId) return
    setApplying(true)
    setError(null)
    try {
      const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/columns/manual`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ columns }),
      })
      if (!res.ok) {
        const err = await res.json().catch(() => ({ detail: res.statusText }))
        throw new Error(err.detail || 'Manuelle Spalten konnten nicht gespeichert werden')
      }
      const data = await res.json()
      setColumnResult({
        columns: data.columns,
        duration_seconds: data.duration_seconds ?? 0,
      })
      setViewMode('normal')
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Fehler beim Speichern')
    } finally {
      setApplying(false)
    }
  }, [sessionId])

  const handleGtApply = useCallback(async (columns: PageRegion[]) => {
    if (!sessionId) return
    setApplying(true)
    setError(null)
    try {
      const gt: ColumnGroundTruth = {
        is_correct: false,
        corrected_columns: columns,
      }
      await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/ground-truth/columns`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(gt),
      })
      setSavedGtColumns(columns)
      setViewMode('normal')
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Fehler beim Speichern')
    } finally {
      setApplying(false)
    }
  }, [sessionId])

  // Count box zones from column result
  const boxZones = columnResult?.zones?.filter(z => z.zone_type === 'box') || []
  const boxCount = boxZones.length

  const createBoxSessions = useCallback(async () => {
    if (!sessionId) return
    setCreatingBoxSessions(true)
    setError(null)
    try {
      const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/create-box-sessions`, {
        method: 'POST',
      })
      if (!res.ok) {
        const err = await res.json().catch(() => ({ detail: res.statusText }))
        throw new Error(err.detail || 'Box-Sessions konnten nicht erstellt werden')
      }
      const data = await res.json()
      const subs: SubSession[] = data.sub_sessions.map((s: { id: string; name?: string; box_index: number }) => ({
        id: s.id,
        name: s.name || `Box ${s.box_index + 1}`,
        box_index: s.box_index,
        current_step: 1,
        status: 'pending',
      }))
      setExistingSubSessions(subs)
      onBoxSessionsCreated?.(subs)
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Fehler beim Erstellen der Box-Sessions')
    } finally {
      setCreatingBoxSessions(false)
    }
  }, [sessionId, onBoxSessionsCreated])

  if (!sessionId) {
    return (
      <div className="flex flex-col items-center justify-center py-16 text-center">
        <div className="text-5xl mb-4">📊</div>
        <h3 className="text-lg font-medium text-gray-700 dark:text-gray-300 mb-2">
          Schritt 3: Spaltenerkennung
        </h3>
        <p className="text-gray-500 dark:text-gray-400 max-w-md">
          Bitte zuerst Schritt 1 und 2 abschliessen.
        </p>
      </div>
    )
  }

  const dewarpedUrl = `${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/cropped`
  const overlayUrl = `${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/columns-overlay`

  // Pre-compute editor state from saved GT or auto columns for GT mode
  const gtInitial = savedGtColumns
    ? columnsToEditorState(savedGtColumns, imageDimensions?.width ?? 1000)
    : undefined

  return (
    <div className="space-y-4">
      {/* Loading indicator */}
      {detecting && (
        <div className="flex items-center gap-2 text-teal-600 dark:text-teal-400 text-sm">
          <div className="animate-spin w-4 h-4 border-2 border-teal-500 border-t-transparent rounded-full" />
          Spaltenerkennung laeuft...
        </div>
      )}

      {viewMode === 'manual' ? (
        /* Manual column editor - overwrites column_result */
        <ManualColumnEditor
          imageUrl={dewarpedUrl}
          imageWidth={imageDimensions?.width ?? 1000}
          imageHeight={imageDimensions?.height ?? 1400}
          onApply={handleManualApply}
          onCancel={() => setViewMode('normal')}
          applying={applying}
          mode="manual"
        />
      ) : viewMode === 'ground-truth' ? (
        /* GT mode: auto result (left, readonly) + GT editor (right) */
        <div className="grid grid-cols-2 gap-4">
          {/* Left: Auto result (readonly overlay) */}
          <div>
            <div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
              Auto-Ergebnis (readonly)
            </div>
            <div className="border rounded-lg overflow-hidden dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
              {columnResult ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  src={`${overlayUrl}?t=${Date.now()}`}
                  alt="Auto Spalten-Overlay"
                  className="w-full h-auto"
                />
              ) : (
                <div className="aspect-[3/4] flex items-center justify-center text-gray-400 text-sm">
                  Keine Auto-Daten
                </div>
              )}
            </div>
            {/* Auto column list */}
            {columnResult && (
              <div className="mt-2 space-y-1">
                <div className="text-xs font-medium text-gray-500 dark:text-gray-400">
                  Auto: {columnResult.columns.length} Spalten
                </div>
                {columnResult.columns
                  .filter(c => c.type.startsWith('column') || c.type === 'page_ref')
                  .map((col, i) => (
                    <div key={i} className="text-xs text-gray-500 dark:text-gray-400 font-mono">
                      {i + 1}. {col.type} x={col.x} w={col.width}
                    </div>
                  ))}
              </div>
            )}
          </div>

          {/* Right: GT editor */}
          <div>
            <div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
              Ground Truth Editor
            </div>
            <ManualColumnEditor
              imageUrl={dewarpedUrl}
              imageWidth={imageDimensions?.width ?? 1000}
              imageHeight={imageDimensions?.height ?? 1400}
              onApply={handleGtApply}
              onCancel={() => setViewMode('normal')}
              applying={applying}
              mode="ground-truth"
              layout="stacked"
              initialDividers={gtInitial?.dividers}
              initialColumnTypes={gtInitial?.columnTypes}
            />
          </div>
        </div>
      ) : (
        /* Normal mode: overlay (left) vs clean (right) */
        <div className="grid grid-cols-2 gap-4">
          <div>
            <div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
              Mit Spalten-Overlay
            </div>
            <div className="border rounded-lg overflow-hidden dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
              {columnResult ? (
                // eslint-disable-next-line @next/next/no-img-element
                <img
                  src={`${overlayUrl}?t=${Date.now()}`}
                  alt="Spalten-Overlay"
                  className="w-full h-auto"
                />
              ) : (
                <div className="aspect-[3/4] flex items-center justify-center text-gray-400 text-sm">
                  {detecting ? 'Erkenne Spalten...' : 'Keine Daten'}
                </div>
              )}
            </div>
          </div>
          <div>
            <div className="text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
              Entzerrtes Bild
            </div>
            <div className="border rounded-lg overflow-hidden dark:border-gray-700 bg-gray-50 dark:bg-gray-900">
              {/* eslint-disable-next-line @next/next/no-img-element */}
              <img
                src={dewarpedUrl}
                alt="Entzerrt"
                className="w-full h-auto"
              />
            </div>
          </div>
        </div>
      )}

      {/* Box zone info */}
      {viewMode === 'normal' && boxCount > 0 && (
        <div className="bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-700 rounded-xl p-4 flex items-center justify-between">
          <div className="flex items-center gap-3">
            <span className="text-2xl">📦</span>
            <div>
              <div className="text-sm font-medium text-amber-800 dark:text-amber-300">
                {boxCount} Box{boxCount > 1 ? 'en' : ''} erkannt
              </div>
              <div className="text-xs text-amber-600 dark:text-amber-400">
                Box-Bereiche werden separat verarbeitet
              </div>
            </div>
          </div>
          {existingSubSessions && existingSubSessions.length > 0 ? (
            <div className="text-xs text-amber-700 dark:text-amber-300 font-medium">
              {existingSubSessions.length} Box-Session{existingSubSessions.length > 1 ? 's' : ''} vorhanden
            </div>
          ) : (
            <button
              onClick={createBoxSessions}
              disabled={creatingBoxSessions}
              className="px-4 py-2 bg-amber-600 text-white rounded-lg hover:bg-amber-700 transition-colors text-sm font-medium disabled:opacity-50 flex items-center gap-2"
            >
              {creatingBoxSessions && (
                <div className="animate-spin w-3.5 h-3.5 border-2 border-white border-t-transparent rounded-full" />
              )}
              Box-Sessions erstellen
            </button>
          )}
        </div>
      )}

      {/* Controls */}
      {viewMode === 'normal' && (
        <ColumnControls
          columnResult={columnResult}
          onRerun={handleRerun}
          onManualMode={() => setViewMode('manual')}
          onGtMode={() => setViewMode('ground-truth')}
          onGroundTruth={handleGroundTruth}
          onNext={onNext}
          isDetecting={detecting}
          savedGtColumns={savedGtColumns}
        />
      )}

      {error && (
        <div className="p-3 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 rounded-lg text-sm">
          {error}
        </div>
      )}
    </div>
  )
}
