/**
 * Batch Uploader Component
 *
 * Multi-file upload with drag & drop, progress tracking, and SSE integration.
 * Supports batch OCR processing for multiple images.
 *
 * Phase 2.1: Batch Processing UI
 */

'use client'

import { useState, useRef, useCallback, useEffect } from 'react'

interface UploadedFile {
  id: string
  file: File
  preview: string
  status: 'pending' | 'processing' | 'completed' | 'error'
  result?: {
    text: string
    confidence: number
    processing_time_ms: number
  }
  error?: string
}

interface BatchUploaderProps {
  /** API base URL */
  apiBase: string
  /** Maximum files allowed */
  maxFiles?: number
  /** Whether to auto-start OCR after upload */
  autoProcess?: boolean
  /** Callback when all files are processed */
  onComplete?: (results: UploadedFile[]) => void
  /** Callback when a single file is processed */
  onFileProcessed?: (file: UploadedFile) => void
  /** Custom class names */
  className?: string
}

/**
 * Generate unique ID
 */
function generateId(): string {
  return Math.random().toString(36).substring(2, 11)
}

/**
 * Batch Uploader Component
 */
export function BatchUploader({
  apiBase,
  maxFiles = 20,
  autoProcess = false,
  onComplete,
  onFileProcessed,
  className = ''
}: BatchUploaderProps) {
  const [files, setFiles] = useState<UploadedFile[]>([])
  const [isProcessing, setIsProcessing] = useState(false)
  const [isDragActive, setIsDragActive] = useState(false)
  const [progress, setProgress] = useState({ current: 0, total: 0 })
  const fileInputRef = useRef<HTMLInputElement>(null)
  const eventSourceRef = useRef<EventSource | null>(null)

  // Add files to the list
  const addFiles = useCallback((newFiles: FileList | File[]) => {
    const fileArray = Array.from(newFiles)
    const imageFiles = fileArray.filter(f => f.type.startsWith('image/'))

    if (imageFiles.length === 0) return

    const uploadedFiles: UploadedFile[] = imageFiles
      .slice(0, maxFiles - files.length)
      .map(file => ({
        id: generateId(),
        file,
        preview: URL.createObjectURL(file),
        status: 'pending' as const
      }))

    setFiles(prev => [...prev, ...uploadedFiles].slice(0, maxFiles))

    // Auto-process if enabled
    if (autoProcess && uploadedFiles.length > 0) {
      setTimeout(() => startProcessing(), 100)
    }
  }, [files.length, maxFiles, autoProcess])

  // Remove a file
  const removeFile = useCallback((id: string) => {
    setFiles(prev => {
      const file = prev.find(f => f.id === id)
      if (file) {
        URL.revokeObjectURL(file.preview)
      }
      return prev.filter(f => f.id !== id)
    })
  }, [])

  // Clear all files
  const clearAll = useCallback(() => {
    files.forEach(f => URL.revokeObjectURL(f.preview))
    setFiles([])
    setProgress({ current: 0, total: 0 })
  }, [files])

  // Start batch processing with SSE
  const startProcessing = useCallback(async () => {
    if (isProcessing || files.length === 0) return

    const pendingFiles = files.filter(f => f.status === 'pending')
    if (pendingFiles.length === 0) return

    setIsProcessing(true)
    setProgress({ current: 0, total: pendingFiles.length })

    // Close any existing connection
    if (eventSourceRef.current) {
      eventSourceRef.current.close()
    }

    // Use SSE for progress updates
    const eventSource = new EventSource(
      `${apiBase}/api/v1/admin/training/ocr/stream?images_count=${pendingFiles.length}`
    )
    eventSourceRef.current = eventSource

    let processedIndex = 0

    eventSource.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data)

        if (data.type === 'progress') {
          setProgress({ current: data.current, total: data.total })

          // Update file status
          if (processedIndex < pendingFiles.length) {
            const currentFile = pendingFiles[processedIndex]
            setFiles(prev => prev.map(f =>
              f.id === currentFile.id
                ? {
                    ...f,
                    status: 'completed' as const,
                    result: data.result
                  }
                : f
            ))

            onFileProcessed?.({
              ...currentFile,
              status: 'completed',
              result: data.result
            })

            processedIndex++
          }
        } else if (data.type === 'error') {
          if (processedIndex < pendingFiles.length) {
            const currentFile = pendingFiles[processedIndex]
            setFiles(prev => prev.map(f =>
              f.id === currentFile.id
                ? { ...f, status: 'error' as const, error: data.error }
                : f
            ))
            processedIndex++
          }
        } else if (data.type === 'complete') {
          eventSource.close()
          setIsProcessing(false)
          onComplete?.(files)
        }
      } catch (e) {
        console.error('SSE parse error:', e)
      }
    }

    eventSource.onerror = () => {
      eventSource.close()
      setIsProcessing(false)
      // Mark remaining as error
      setFiles(prev => prev.map(f =>
        f.status === 'pending' || f.status === 'processing'
          ? { ...f, status: 'error' as const, error: 'Verbindung unterbrochen' }
          : f
      ))
    }

    // Mark files as processing
    setFiles(prev => prev.map(f =>
      f.status === 'pending' ? { ...f, status: 'processing' as const } : f
    ))
  }, [apiBase, files, isProcessing, onComplete, onFileProcessed])

  // Stop processing
  const stopProcessing = useCallback(() => {
    if (eventSourceRef.current) {
      eventSourceRef.current.close()
      eventSourceRef.current = null
    }
    setIsProcessing(false)
    setFiles(prev => prev.map(f =>
      f.status === 'processing' ? { ...f, status: 'pending' as const } : f
    ))
  }, [])

  // Drag handlers
  const handleDragEnter = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setIsDragActive(true)
  }

  const handleDragLeave = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setIsDragActive(false)
  }

  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault()
    e.stopPropagation()
    setIsDragActive(false)
    addFiles(e.dataTransfer.files)
  }

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      files.forEach(f => URL.revokeObjectURL(f.preview))
      if (eventSourceRef.current) {
        eventSourceRef.current.close()
      }
    }
  }, [])

  const completedCount = files.filter(f => f.status === 'completed').length
  const errorCount = files.filter(f => f.status === 'error').length
  const avgConfidence = files
    .filter(f => f.result)
    .reduce((sum, f) => sum + (f.result?.confidence || 0), 0) /
    Math.max(1, files.filter(f => f.result).length)

  return (
    <div className={`space-y-4 ${className}`}>
      {/* Upload area */}
      <div
        className={`border-2 border-dashed rounded-xl p-8 text-center cursor-pointer transition-all ${
          isDragActive
            ? 'border-purple-500 bg-purple-50'
            : 'border-slate-300 hover:border-purple-400 hover:bg-purple-50/50'
        }`}
        onDragEnter={handleDragEnter}
        onDragOver={(e) => e.preventDefault()}
        onDragLeave={handleDragLeave}
        onDrop={handleDrop}
        onClick={() => fileInputRef.current?.click()}
      >
        <div className="text-4xl mb-3">📁</div>
        <div className="text-slate-700 font-medium">
          {isDragActive
            ? 'Loslassen zum Hochladen'
            : 'Bilder hierher ziehen oder klicken'}
        </div>
        <div className="text-sm text-slate-400 mt-1">
          Bis zu {maxFiles} Bilder (PNG, JPG)
        </div>
        <input
          ref={fileInputRef}
          type="file"
          accept="image/*"
          multiple
          className="hidden"
          onChange={(e) => e.target.files && addFiles(e.target.files)}
        />
      </div>

      {/* File list */}
      {files.length > 0 && (
        <div className="space-y-3">
          {/* Header with stats */}
          <div className="flex items-center justify-between">
            <div className="text-sm text-slate-600">
              {files.length} Bilder ausgewaehlt
              {completedCount > 0 && (
                <span className="text-green-600 ml-2">
                  ({completedCount} verarbeitet, {(avgConfidence * 100).toFixed(0)}% Konfidenz)
                </span>
              )}
              {errorCount > 0 && (
                <span className="text-red-600 ml-2">({errorCount} Fehler)</span>
              )}
            </div>
            <div className="flex items-center gap-2">
              <button
                onClick={clearAll}
                className="px-3 py-1 text-sm text-slate-600 hover:text-slate-900 transition-colors"
              >
                Alle entfernen
              </button>
              {isProcessing ? (
                <button
                  onClick={stopProcessing}
                  className="px-4 py-1.5 bg-red-600 hover:bg-red-700 text-white rounded-lg text-sm font-medium transition-colors"
                >
                  Stoppen
                </button>
              ) : (
                <button
                  onClick={startProcessing}
                  disabled={files.filter(f => f.status === 'pending').length === 0}
                  className="px-4 py-1.5 bg-purple-600 hover:bg-purple-700 disabled:bg-slate-300 text-white rounded-lg text-sm font-medium transition-colors"
                >
                  OCR starten
                </button>
              )}
            </div>
          </div>

          {/* Progress bar */}
          {isProcessing && (
            <div className="bg-slate-100 rounded-lg p-3">
              <div className="flex items-center justify-between text-sm mb-2">
                <span className="text-slate-600">
                  Verarbeite Bild {progress.current} von {progress.total}
                </span>
                <span className="text-purple-600 font-medium">
                  {((progress.current / progress.total) * 100).toFixed(0)}%
                </span>
              </div>
              <div className="h-2 bg-slate-200 rounded-full overflow-hidden">
                <div
                  className="h-full bg-purple-600 transition-all duration-300"
                  style={{ width: `${(progress.current / progress.total) * 100}%` }}
                />
              </div>
            </div>
          )}

          {/* File thumbnails */}
          <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-3">
            {files.map((file) => (
              <div
                key={file.id}
                className={`relative group rounded-lg overflow-hidden border-2 ${
                  file.status === 'completed'
                    ? 'border-green-300'
                    : file.status === 'error'
                    ? 'border-red-300'
                    : file.status === 'processing'
                    ? 'border-purple-300'
                    : 'border-slate-200'
                }`}
              >
                {/* Thumbnail */}
                <img
                  src={file.preview}
                  alt={file.file.name}
                  className="w-full h-24 object-cover"
                />

                {/* Overlay for status */}
                {file.status === 'processing' && (
                  <div className="absolute inset-0 bg-purple-900/50 flex items-center justify-center">
                    <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-white"></div>
                  </div>
                )}

                {file.status === 'completed' && file.result && (
                  <div className="absolute inset-0 bg-green-900/70 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity">
                    <div className="text-center text-white text-xs p-2">
                      <div className="font-medium">
                        {(file.result.confidence * 100).toFixed(0)}%
                      </div>
                      <div className="text-green-200 truncate max-w-full">
                        {file.result.text.substring(0, 30)}...
                      </div>
                    </div>
                  </div>
                )}

                {file.status === 'error' && (
                  <div className="absolute inset-0 bg-red-900/70 flex items-center justify-center">
                    <div className="text-white text-xs text-center px-2">
                      Fehler
                    </div>
                  </div>
                )}

                {/* Status badge */}
                <div className={`absolute top-1 right-1 w-3 h-3 rounded-full ${
                  file.status === 'completed'
                    ? 'bg-green-500'
                    : file.status === 'error'
                    ? 'bg-red-500'
                    : file.status === 'processing'
                    ? 'bg-purple-500 animate-pulse'
                    : 'bg-slate-400'
                }`} />

                {/* Remove button */}
                {!isProcessing && (
                  <button
                    onClick={(e) => {
                      e.stopPropagation()
                      removeFile(file.id)
                    }}
                    className="absolute top-1 left-1 w-5 h-5 bg-red-500 text-white rounded-full opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center text-xs"
                  >
                    ×
                  </button>
                )}

                {/* File name */}
                <div className="absolute bottom-0 left-0 right-0 bg-black/60 text-white text-xs px-2 py-1 truncate">
                  {file.file.name}
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Results summary */}
      {completedCount > 0 && !isProcessing && (
        <div className="bg-green-50 border border-green-200 rounded-lg p-4">
          <h4 className="font-medium text-green-800 mb-2">
            Verarbeitung abgeschlossen
          </h4>
          <div className="grid grid-cols-3 gap-4 text-center text-sm">
            <div>
              <div className="text-2xl font-bold text-green-700">{completedCount}</div>
              <div className="text-green-600">Erfolgreich</div>
            </div>
            <div>
              <div className="text-2xl font-bold text-slate-700">
                {(avgConfidence * 100).toFixed(0)}%
              </div>
              <div className="text-slate-600">Durchschnittl. Konfidenz</div>
            </div>
            <div>
              <div className="text-2xl font-bold text-red-700">{errorCount}</div>
              <div className="text-red-600">Fehler</div>
            </div>
          </div>
        </div>
      )}
    </div>
  )
}

export default BatchUploader
