'use client'

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

interface UploadedFile {
  id: string
  name: string
  size: number
  progress: number
  status: 'pending' | 'uploading' | 'complete' | 'error'
  error?: string
}

function formatFileSize(bytes: number): string {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
}

const CHUNK_SIZE = 5 * 1024 * 1024 // 5 MB chunks

export default function UploadPage() {
  const [files, setFiles] = useState<UploadedFile[]>([])
  const [isDragging, setIsDragging] = useState(false)
  const [serverUrl, setServerUrl] = useState('')
  const [uploadDestination, setUploadDestination] = useState<'klausur' | 'rag'>('klausur')

  useEffect(() => {
    // Detect server URL from current location
    if (typeof window !== 'undefined') {
      const hostname = window.location.hostname
      // If localhost or local IP, use klausur-service port
      if (hostname === 'localhost' || hostname.startsWith('192.168.')) {
        setServerUrl(`http://${hostname}:8086`)
      } else {
        setServerUrl('/api/klausur')
      }
    }
  }, [])

  const uploadChunked = async (file: File, fileId: string) => {
    const totalChunks = Math.ceil(file.size / CHUNK_SIZE)
    let uploadedChunks = 0

    // Create upload session
    const sessionResponse = await fetch(`${serverUrl}/api/v1/upload/init`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        filename: file.name,
        filesize: file.size,
        chunks: totalChunks,
        destination: uploadDestination
      })
    })

    if (!sessionResponse.ok) {
      throw new Error('Konnte Upload-Session nicht starten')
    }

    const { upload_id } = await sessionResponse.json()

    // Upload chunks
    for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
      const start = chunkIndex * CHUNK_SIZE
      const end = Math.min(start + CHUNK_SIZE, file.size)
      const chunk = file.slice(start, end)

      const formData = new FormData()
      formData.append('chunk', chunk)
      formData.append('upload_id', upload_id)
      formData.append('chunk_index', chunkIndex.toString())

      const chunkResponse = await fetch(`${serverUrl}/api/v1/upload/chunk`, {
        method: 'POST',
        body: formData
      })

      if (!chunkResponse.ok) {
        throw new Error(`Fehler beim Hochladen von Teil ${chunkIndex + 1}`)
      }

      uploadedChunks++
      const progress = Math.round((uploadedChunks / totalChunks) * 100)

      setFiles(prev => prev.map(f =>
        f.id === fileId ? { ...f, progress } : f
      ))
    }

    // Finalize upload
    const finalizeFormData = new FormData()
    finalizeFormData.append('upload_id', upload_id)
    const finalizeResponse = await fetch(`${serverUrl}/api/v1/upload/finalize`, {
      method: 'POST',
      body: finalizeFormData
    })

    if (!finalizeResponse.ok) {
      throw new Error('Fehler beim Abschliessen des Uploads')
    }

    return await finalizeResponse.json()
  }

  const uploadFile = async (file: File) => {
    const fileId = Math.random().toString(36).substr(2, 9)

    setFiles(prev => [...prev, {
      id: fileId,
      name: file.name,
      size: file.size,
      progress: 0,
      status: 'pending'
    }])

    try {
      setFiles(prev => prev.map(f =>
        f.id === fileId ? { ...f, status: 'uploading' } : f
      ))

      // For large files (>10MB), use chunked upload
      if (file.size > 10 * 1024 * 1024) {
        await uploadChunked(file, fileId)
      } else {
        // Simple upload for smaller files
        const formData = new FormData()
        formData.append('file', file)
        formData.append('destination', uploadDestination)

        const response = await fetch(`${serverUrl}/api/v1/upload/simple`, {
          method: 'POST',
          body: formData
        })

        if (!response.ok) {
          throw new Error('Upload fehlgeschlagen')
        }

        setFiles(prev => prev.map(f =>
          f.id === fileId ? { ...f, progress: 100 } : f
        ))
      }

      setFiles(prev => prev.map(f =>
        f.id === fileId ? { ...f, status: 'complete', progress: 100 } : f
      ))
    } catch (error) {
      setFiles(prev => prev.map(f =>
        f.id === fileId ? {
          ...f,
          status: 'error',
          error: error instanceof Error ? error.message : 'Unbekannter Fehler'
        } : f
      ))
    }
  }

  const handleFiles = useCallback((fileList: FileList | File[]) => {
    const newFiles = Array.from(fileList).filter(f => f.type === 'application/pdf')
    newFiles.forEach(file => uploadFile(file))
  }, [serverUrl, uploadDestination])

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setIsDragging(false)
    handleFiles(e.dataTransfer.files)
  }, [handleFiles])

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setIsDragging(true)
  }, [])

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setIsDragging(false)
  }, [])

  const handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      handleFiles(e.target.files)
    }
  }, [handleFiles])

  const removeFile = (fileId: string) => {
    setFiles(prev => prev.filter(f => f.id !== fileId))
  }

  const completedCount = files.filter(f => f.status === 'complete').length
  const totalSize = files.reduce((sum, f) => sum + f.size, 0)

  return (
    <div className="min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 text-white">
      {/* Header */}
      <header className="p-4 border-b border-slate-700">
        <div className="max-w-2xl mx-auto flex items-center justify-between">
          <h1 className="text-xl font-bold text-blue-400">
            BreakPilot Upload
          </h1>
          <span className="text-xs text-slate-400 bg-slate-800 px-2 py-1 rounded">
            DSGVO-konform
          </span>
        </div>
      </header>

      <main className="max-w-2xl mx-auto p-4 space-y-6">
        {/* Destination Selector */}
        <div className="flex gap-2">
          <button
            onClick={() => setUploadDestination('klausur')}
            className={`flex-1 py-3 px-4 rounded-lg font-medium transition-all ${
              uploadDestination === 'klausur'
                ? 'bg-blue-600 text-white shadow-lg shadow-blue-500/25'
                : 'bg-slate-800 text-slate-300 hover:bg-slate-700'
            }`}
          >
            Klausuren
          </button>
          <button
            onClick={() => setUploadDestination('rag')}
            className={`flex-1 py-3 px-4 rounded-lg font-medium transition-all ${
              uploadDestination === 'rag'
                ? 'bg-purple-600 text-white shadow-lg shadow-purple-500/25'
                : 'bg-slate-800 text-slate-300 hover:bg-slate-700'
            }`}
          >
            Erwartungshorizonte
          </button>
        </div>

        {/* Drop Zone */}
        <div
          onDrop={handleDrop}
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          className={`
            relative border-2 border-dashed rounded-2xl p-8 text-center transition-all
            ${isDragging
              ? 'border-blue-400 bg-blue-500/10 scale-[1.02]'
              : 'border-slate-600 bg-slate-800/50 hover:border-slate-500'
            }
          `}
        >
          <input
            type="file"
            accept=".pdf"
            multiple
            onChange={handleFileSelect}
            className="absolute inset-0 w-full h-full opacity-0 cursor-pointer"
          />

          <div className="space-y-4">
            <div className="w-16 h-16 mx-auto bg-slate-700 rounded-full flex items-center justify-center">
              <svg className="w-8 h-8 text-blue-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" />
              </svg>
            </div>

            <div>
              <p className="text-lg font-medium text-slate-200">
                PDF-Dateien hochladen
              </p>
              <p className="text-sm text-slate-400 mt-1">
                Tippen zum Auswaehlen oder hierher ziehen
              </p>
            </div>

            <div className="text-xs text-slate-500">
              Grosse Dateien bis 200 MB werden automatisch in Teilen hochgeladen
            </div>
          </div>
        </div>

        {/* Stats */}
        {files.length > 0 && (
          <div className="flex justify-between text-sm text-slate-400 px-2">
            <span>{completedCount} von {files.length} fertig</span>
            <span>{formatFileSize(totalSize)} gesamt</span>
          </div>
        )}

        {/* File List */}
        <div className="space-y-3">
          {files.map(file => (
            <div
              key={file.id}
              className={`
                bg-slate-800 rounded-xl p-4 transition-all
                ${file.status === 'error' ? 'ring-2 ring-red-500/50' : ''}
                ${file.status === 'complete' ? 'ring-2 ring-green-500/30' : ''}
              `}
            >
              <div className="flex items-start justify-between gap-3">
                <div className="flex-1 min-w-0">
                  <p className="font-medium text-slate-200 truncate">
                    {file.name}
                  </p>
                  <p className="text-sm text-slate-400">
                    {formatFileSize(file.size)}
                  </p>
                </div>

                <button
                  onClick={() => removeFile(file.id)}
                  className="p-1 text-slate-500 hover:text-slate-300 transition-colors"
                >
                  <svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                  </svg>
                </button>
              </div>

              {/* Progress Bar */}
              {(file.status === 'uploading' || file.status === 'pending') && (
                <div className="mt-3">
                  <div className="h-2 bg-slate-700 rounded-full overflow-hidden">
                    <div
                      className="h-full bg-gradient-to-r from-blue-500 to-blue-400 transition-all duration-300"
                      style={{ width: `${file.progress}%` }}
                    />
                  </div>
                  <p className="text-xs text-slate-400 mt-1">
                    {file.progress}% hochgeladen
                  </p>
                </div>
              )}

              {/* Status */}
              {file.status === 'complete' && (
                <div className="mt-3 flex items-center gap-2 text-green-400 text-sm">
                  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                  </svg>
                  Erfolgreich hochgeladen
                </div>
              )}

              {file.status === 'error' && (
                <div className="mt-3 flex items-center gap-2 text-red-400 text-sm">
                  <svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                  </svg>
                  {file.error || 'Fehler beim Hochladen'}
                </div>
              )}
            </div>
          ))}
        </div>

        {/* Info Box */}
        <div className="bg-slate-800/50 rounded-xl p-4 text-sm text-slate-400">
          <p className="font-medium text-slate-300 mb-2">Hinweise:</p>
          <ul className="space-y-1 list-disc list-inside">
            <li>Die Dateien werden lokal im WLAN uebertragen</li>
            <li>Keine Daten werden ins Internet gesendet</li>
            <li>Unterstuetzte Formate: PDF</li>
          </ul>
        </div>

        {/* Server Info */}
        <div className="text-center text-xs text-slate-500">
          Server: {serverUrl || 'Wird ermittelt...'}
        </div>
      </main>
    </div>
  )
}
