'use client'

import { useCallback, 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 {
  onNext: (sessionId: string) => void
}

export function StepDeskew({ onNext }: StepDeskewProps) {
  const [session, setSession] = useState<SessionInfo | null>(null)
  const [deskewResult, setDeskewResult] = useState<DeskewResult | null>(null)
  const [uploading, setUploading] = useState(false)
  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 [dragOver, setDragOver] = useState(false)

  const handleUpload = useCallback(async (file: File) => {
    setUploading(true)
    setError(null)
    setDeskewResult(null)

    try {
      const formData = new FormData()
      formData.append('file', file)

      const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions`, {
        method: 'POST',
        body: formData,
      })

      if (!res.ok) {
        const err = await res.json().catch(() => ({ detail: res.statusText }))
        throw new Error(err.detail || 'Upload fehlgeschlagen')
      }

      const data: SessionInfo = await res.json()
      // Prepend API prefix to relative URLs
      data.original_image_url = `${KLAUSUR_API}${data.original_image_url}`
      setSession(data)

      // Auto-trigger deskew
      setDeskewing(true)
      const deskewRes = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${data.session_id}/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 : 'Unbekannter Fehler')
    } finally {
      setUploading(false)
      setDeskewing(false)
    }
  }, [])

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

    try {
      const res = await fetch(`${KLAUSUR_API}/api/v1/ocr-pipeline/sessions/${session.session_id}/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,
              // Force reload by appending timestamp
              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)
    }
  }, [session])

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

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setDragOver(false)
    const file = e.dataTransfer.files[0]
    if (file) handleUpload(file)
  }, [handleUpload])

  const handleFileInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0]
    if (file) handleUpload(file)
  }, [handleUpload])

  // Upload area (no session yet)
  if (!session) {
    return (
      <div className="space-y-4">
        <div
          onDragOver={(e) => { e.preventDefault(); setDragOver(true) }}
          onDragLeave={() => setDragOver(false)}
          onDrop={handleDrop}
          className={`border-2 border-dashed rounded-xl p-12 text-center transition-colors ${
            dragOver
              ? 'border-teal-400 bg-teal-50 dark:bg-teal-900/20'
              : 'border-gray-300 dark:border-gray-600 hover:border-teal-400'
          }`}
        >
          {uploading ? (
            <div className="text-gray-500">
              <div className="animate-spin inline-block w-8 h-8 border-2 border-teal-500 border-t-transparent rounded-full mb-3" />
              <p>Wird hochgeladen...</p>
            </div>
          ) : (
            <>
              <div className="text-4xl mb-3">📄</div>
              <p className="text-gray-600 dark:text-gray-400 mb-2">
                PDF oder Bild hierher ziehen
              </p>
              <p className="text-sm text-gray-400 mb-4">oder</p>
              <label className="inline-block px-4 py-2 bg-teal-600 text-white rounded-lg cursor-pointer hover:bg-teal-700 transition-colors">
                Datei auswaehlen
                <input
                  type="file"
                  accept=".pdf,.png,.jpg,.jpeg,.tiff,.tif"
                  onChange={handleFileInput}
                  className="hidden"
                />
              </label>
            </>
          )}
        </div>
        {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>
    )
  }

  // Session active: show comparison + controls
  return (
    <div className="space-y-4">
      {/* Filename */}
      <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 */}
      <ImageCompareView
        originalUrl={session.original_image_url}
        deskewedUrl={deskewResult?.deskewed_image_url ?? null}
        showGrid={showGrid}
        showBinarized={showBinarized}
        binarizedUrl={deskewResult?.binarized_image_url ?? null}
      />

      {/* Controls */}
      <DeskewControls
        deskewResult={deskewResult}
        showBinarized={showBinarized}
        onToggleBinarized={() => setShowBinarized((v) => !v)}
        showGrid={showGrid}
        onToggleGrid={() => setShowGrid((v) => !v)}
        onManualDeskew={handleManualDeskew}
        onGroundTruth={handleGroundTruth}
        onNext={() => session && onNext(session.session_id)}
        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>
  )
}
