'use client'

import { useCallback, useEffect, useState } from 'react'
import type { DeskewGroundTruth, DeskewResult, SessionInfo } from '@/app/(admin)/ai/ocr-pipeline/types'
import { DeskewControls } from './DeskewControls'
import { ImageCompareView } from './ImageCompareView'

const KLAUSUR_API = '/klausur-api'

interface StepDeskewProps {
  sessionId: string | null
  onNext: () => void
}

export function StepDeskew({ sessionId, onNext }: StepDeskewProps) {
  const [session, setSession] = useState<SessionInfo | null>(null)
  const [deskewResult, setDeskewResult] = useState<DeskewResult | null>(null)
  const [deskewing, setDeskewing] = useState(false)
  const [applying, setApplying] = useState(false)
  const [showBinarized, setShowBinarized] = useState(false)
  const [showGrid, setShowGrid] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [hasAutoRun, setHasAutoRun] = useState(false)

  // Load session and auto-trigger deskew
  useEffect(() => {
    if (!sessionId || session) return

    const loadAndDeskew = async () => {
      try {
        const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}`)
        if (!res.ok) return
        const data = await res.json()

        const sessionInfo: SessionInfo = {
          session_id: data.session_id,
          filename: data.filename,
          image_width: data.image_width,
          image_height: data.image_height,
          // Use oriented image as "before" view (deskew runs right after orientation)
          original_image_url: `${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/oriented`,
        }
        setSession(sessionInfo)

        // If deskew result already exists, use it
        if (data.deskew_result) {
          const dr: DeskewResult = {
            ...data.deskew_result,
            deskewed_image_url: `${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/deskewed`,
            binarized_image_url: `${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/image/binarized`,
          }
          setDeskewResult(dr)
          return
        }

        // Auto-trigger deskew if not already done
        if (!hasAutoRun) {
          setHasAutoRun(true)
          setDeskewing(true)
          const deskewRes = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/deskew`, {
            method: 'POST',
          })

          if (!deskewRes.ok) {
            throw new Error('Begradigung fehlgeschlagen')
          }

          const deskewData: DeskewResult = await deskewRes.json()
          deskewData.deskewed_image_url = `${KLAUSUR_API}${deskewData.deskewed_image_url}`
          deskewData.binarized_image_url = `${KLAUSUR_API}${deskewData.binarized_image_url}`
          setDeskewResult(deskewData)
        }
      } catch (e) {
        setError(e instanceof Error ? e.message : 'Fehler beim Laden')
      } finally {
        setDeskewing(false)
      }
    }

    loadAndDeskew()
  }, [sessionId, session, hasAutoRun])

  const handleManualDeskew = useCallback(async (angle: number) => {
    if (!sessionId) return
    setApplying(true)
    setError(null)

    try {
      const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${sessionId}/deskew/manual`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ angle }),
      })

      if (!res.ok) throw new Error('Manuelle Begradigung fehlgeschlagen')

      const data = await res.json()
      setDeskewResult((prev) =>
        prev
          ? {
              ...prev,
              angle_applied: data.angle_applied,
              method_used: data.method_used,
              deskewed_image_url: `${KLAUSUR_API}${data.deskewed_image_url}?t=${Date.now()}`,
            }
          : null,
      )
    } catch (e) {
      setError(e instanceof Error ? e.message : 'Fehler')
    } finally {
      setApplying(false)
    }
  }, [sessionId])

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

  if (!sessionId) {
    return <div className="text-sm text-gray-400">Keine Session ausgewaehlt.</div>
  }

  return (
    <div className="space-y-4">
      {/* Filename */}
      {session && (
        <div className="text-sm text-gray-500 dark:text-gray-400">
          Datei: <span className="font-medium text-gray-700 dark:text-gray-300">{session.filename}</span>
          {' '}({session.image_width} x {session.image_height} px)
        </div>
      )}

      {/* Loading indicator */}
      {deskewing && (
        <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" />
          Begradigung laeuft (beide Methoden)...
        </div>
      )}

      {/* Image comparison */}
      {session && (
        <ImageCompareView
          originalUrl={session.original_image_url}
          deskewedUrl={deskewResult?.deskewed_image_url ?? null}
          showGrid={showGrid}
          showBinarized={showBinarized}
          binarizedUrl={deskewResult?.binarized_image_url ?? null}
          leftLabel="Orientiert"
          rightLabel="Begradigt"
        />
      )}

      {/* Controls */}
      <DeskewControls
        deskewResult={deskewResult}
        showBinarized={showBinarized}
        onToggleBinarized={() => setShowBinarized((v) => !v)}
        showGrid={showGrid}
        onToggleGrid={() => setShowGrid((v) => !v)}
        onManualDeskew={handleManualDeskew}
        onGroundTruth={handleGroundTruth}
        onNext={onNext}
        isApplying={applying}
      />

      {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>
  )
}
