'use client'

/**
 * RAG & Daten-Management Admin Page
 *
 * Manages training data, RAG collections, ingestion, and quality metrics.
 * See: klausur-service/docs/RAG-Admin-Spec.md
 */

import { useState, useEffect, useCallback } from 'react'
import AdminLayout from '@/components/admin/AdminLayout'

// API Base URL for klausur-service
const API_BASE = process.env.NEXT_PUBLIC_KLAUSUR_SERVICE_URL || 'http://localhost:8086'

// Types
interface Collection {
  name: string
  displayName: string
  bundesland: string
  useCase: string
  documentCount: number
  chunkCount: number
  years: number[]
  subjects: string[]
  status: 'ready' | 'indexing' | 'empty'
}

interface IngestionStatus {
  running: boolean
  lastRun: string | null
  documentsIndexed: number | null
  chunksCreated: number | null
  errors: string[]
}

interface SearchResult {
  id: string
  score: number
  text: string
  year: number | null
  subject: string | null
  niveau: string | null
  taskNumber: number | null
}

// Tab definitions
type TabId = 'collections' | 'upload' | 'ingestion' | 'search' | 'metrics'

const tabs: { id: TabId; name: string; icon: JSX.Element }[] = [
  {
    id: 'collections',
    name: 'Sammlungen',
    icon: (
      <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
      </svg>
    ),
  },
  {
    id: 'upload',
    name: 'Upload',
    icon: (
      <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
      </svg>
    ),
  },
  {
    id: 'ingestion',
    name: 'Ingestion',
    icon: (
      <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
      </svg>
    ),
  },
  {
    id: 'search',
    name: 'Suche & Test',
    icon: (
      <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
      </svg>
    ),
  },
  {
    id: 'metrics',
    name: 'Metriken',
    icon: (
      <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
      </svg>
    ),
  },
]

// Main Component
export default function RAGAdminPage() {
  const [activeTab, setActiveTab] = useState<TabId>('collections')
  const [collections, setCollections] = useState<Collection[]>([])
  const [ingestionStatus, setIngestionStatus] = useState<IngestionStatus | null>(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)

  // Fetch collections and status
  const fetchData = useCallback(async () => {
    try {
      setLoading(true)

      // Fetch collections info
      const collectionsRes = await fetch(`${API_BASE}/api/v1/admin/nibis/collections`)
      const statsRes = await fetch(`${API_BASE}/api/v1/admin/nibis/stats`)
      const statusRes = await fetch(`${API_BASE}/api/v1/admin/nibis/status`)

      if (collectionsRes.ok && statsRes.ok && statusRes.ok) {
        const collectionsData = await collectionsRes.json()
        const statsData = await statsRes.json()
        const statusData = await statusRes.json()

        // Build collections from data
        const cols: Collection[] = []

        // Check if we have the NiBiS collection
        const nibisCollection = collectionsData.collections?.find(
          (c: { name: string }) => c.name === 'bp_nibis_eh'
        )

        if (nibisCollection || statsData.indexed) {
          cols.push({
            name: 'bp_nibis_eh',
            displayName: 'Niedersachsen - Klausurkorrektur',
            bundesland: 'NI',
            useCase: 'klausur',
            documentCount: statsData.total_chunks || nibisCollection?.points_count || 0,
            chunkCount: statsData.total_chunks || nibisCollection?.points_count || 0,
            years: statsData.years || [],
            subjects: statsData.subjects || [],
            status: statusData.running ? 'indexing' : (statsData.indexed ? 'ready' : 'empty'),
          })
        }

        setCollections(cols)
        setIngestionStatus({
          running: statusData.running,
          lastRun: statusData.last_run,
          documentsIndexed: statusData.documents_indexed,
          chunksCreated: statusData.chunks_created,
          errors: statusData.errors || [],
        })
      }

      setError(null)
    } catch (err) {
      console.error('Failed to fetch data:', err)
      setError('Verbindung zum Klausur-Service fehlgeschlagen')
    } finally {
      setLoading(false)
    }
  }, [])

  useEffect(() => {
    fetchData()

    // Refresh every 5 seconds if ingestion is running
    const interval = setInterval(() => {
      if (ingestionStatus?.running) {
        fetchData()
      }
    }, 5000)

    return () => clearInterval(interval)
  }, [fetchData, ingestionStatus?.running])

  return (
    <AdminLayout
      title="Daten & RAG"
      description="Training Data Management und RAG-Sammlungen"
    >
      {/* Error Banner */}
      {error && (
        <div className="mb-6 bg-red-50 border border-red-200 rounded-lg p-4 flex items-center gap-3">
          <svg className="w-5 h-5 text-red-500 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
          </svg>
          <span className="text-red-700">{error}</span>
          <button onClick={fetchData} className="ml-auto text-red-600 hover:text-red-800 text-sm font-medium">
            Erneut versuchen
          </button>
        </div>
      )}

      {/* Tab Navigation */}
      <div className="border-b border-slate-200 mb-6">
        <nav className="-mb-px flex space-x-8">
          {tabs.map((tab) => (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={`
                flex items-center gap-2 py-4 px-1 border-b-2 font-medium text-sm transition-colors
                ${activeTab === tab.id
                  ? 'border-primary-500 text-primary-600'
                  : 'border-transparent text-slate-500 hover:text-slate-700 hover:border-slate-300'
                }
              `}
            >
              {tab.icon}
              {tab.name}
            </button>
          ))}
        </nav>
      </div>

      {/* Tab Content */}
      {activeTab === 'collections' && (
        <CollectionsTab
          collections={collections}
          loading={loading}
          onRefresh={fetchData}
        />
      )}
      {activeTab === 'upload' && (
        <UploadTab onUploadComplete={fetchData} />
      )}
      {activeTab === 'ingestion' && (
        <IngestionTab
          status={ingestionStatus}
          onRefresh={fetchData}
        />
      )}
      {activeTab === 'search' && (
        <SearchTab collections={collections} />
      )}
      {activeTab === 'metrics' && (
        <MetricsTab collections={collections} />
      )}
    </AdminLayout>
  )
}

// ============================================================================
// Collections Tab
// ============================================================================

function CollectionsTab({
  collections,
  loading,
  onRefresh
}: {
  collections: Collection[]
  loading: boolean
  onRefresh: () => void
}) {
  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-lg font-semibold text-slate-900">RAG Sammlungen</h2>
          <p className="text-sm text-slate-500">Verwaltung der indexierten Dokumentensammlungen</p>
        </div>
        <button
          onClick={onRefresh}
          className="px-4 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50"
        >
          Aktualisieren
        </button>
      </div>

      {/* Loading State */}
      {loading && (
        <div className="flex items-center justify-center py-12">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600"></div>
        </div>
      )}

      {/* Collections Grid */}
      {!loading && (
        <div className="grid gap-4">
          {collections.length === 0 ? (
            <div className="bg-slate-50 rounded-lg p-8 text-center">
              <svg className="w-12 h-12 text-slate-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" />
              </svg>
              <h3 className="text-lg font-medium text-slate-900 mb-2">Keine Sammlungen vorhanden</h3>
              <p className="text-slate-500 mb-4">Starten Sie die Ingestion oder laden Sie Dokumente hoch.</p>
            </div>
          ) : (
            collections.map((col) => (
              <CollectionCard key={col.name} collection={col} />
            ))
          )}

          {/* Placeholder for future collections */}
          <div className="border-2 border-dashed border-slate-300 rounded-lg p-6 text-center hover:border-slate-400 transition-colors cursor-pointer">
            <svg className="w-8 h-8 text-slate-400 mx-auto mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
            </svg>
            <span className="text-sm font-medium text-slate-600">Neue Sammlung (demnächst)</span>
          </div>
        </div>
      )}
    </div>
  )
}

function CollectionCard({ collection }: { collection: Collection }) {
  const statusColors = {
    ready: 'bg-green-100 text-green-800',
    indexing: 'bg-yellow-100 text-yellow-800',
    empty: 'bg-slate-100 text-slate-800',
  }

  const statusLabels = {
    ready: 'Bereit',
    indexing: 'Indexierung...',
    empty: 'Leer',
  }

  return (
    <div className="bg-white rounded-lg border border-slate-200 p-6 hover:shadow-md transition-shadow">
      <div className="flex items-start justify-between">
        <div className="flex items-center gap-4">
          <div className="w-12 h-12 bg-primary-100 rounded-lg flex items-center justify-center">
            <svg className="w-6 h-6 text-primary-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
            </svg>
          </div>
          <div>
            <h3 className="text-lg font-semibold text-slate-900">{collection.displayName}</h3>
            <p className="text-sm text-slate-500 font-mono">{collection.name}</p>
          </div>
        </div>
        <span className={`px-3 py-1 rounded-full text-xs font-medium ${statusColors[collection.status]}`}>
          {statusLabels[collection.status]}
        </span>
      </div>

      <div className="mt-4 grid grid-cols-2 md:grid-cols-4 gap-4">
        <div>
          <p className="text-xs text-slate-500 uppercase tracking-wider">Chunks</p>
          <p className="text-lg font-semibold text-slate-900">
            {collection.chunkCount.toLocaleString()}
          </p>
        </div>
        <div>
          <p className="text-xs text-slate-500 uppercase tracking-wider">Jahre</p>
          <p className="text-lg font-semibold text-slate-900">
            {collection.years.length > 0
              ? `${Math.min(...collection.years)}-${Math.max(...collection.years)}`
              : '-'
            }
          </p>
        </div>
        <div>
          <p className="text-xs text-slate-500 uppercase tracking-wider">Fächer</p>
          <p className="text-lg font-semibold text-slate-900">
            {collection.subjects.length}
          </p>
        </div>
        <div>
          <p className="text-xs text-slate-500 uppercase tracking-wider">Bundesland</p>
          <p className="text-lg font-semibold text-slate-900">
            {collection.bundesland}
          </p>
        </div>
      </div>

      {collection.subjects.length > 0 && (
        <div className="mt-4 flex flex-wrap gap-2">
          {collection.subjects.slice(0, 8).map((subject) => (
            <span
              key={subject}
              className="px-2 py-1 bg-slate-100 text-slate-700 text-xs rounded-md"
            >
              {subject}
            </span>
          ))}
          {collection.subjects.length > 8 && (
            <span className="px-2 py-1 bg-slate-100 text-slate-500 text-xs rounded-md">
              +{collection.subjects.length - 8} weitere
            </span>
          )}
        </div>
      )}
    </div>
  )
}

// ============================================================================
// Upload Tab
// ============================================================================

function UploadTab({ onUploadComplete }: { onUploadComplete: () => void }) {
  const [isDragging, setIsDragging] = useState(false)
  const [files, setFiles] = useState<File[]>([])
  const [uploading, setUploading] = useState(false)

  const handleDrop = useCallback((e: React.DragEvent) => {
    e.preventDefault()
    setIsDragging(false)

    const droppedFiles = Array.from(e.dataTransfer.files)
    const validFiles = droppedFiles.filter(
      f => f.name.endsWith('.zip') || f.name.endsWith('.pdf')
    )
    setFiles(prev => [...prev, ...validFiles])
  }, [])

  const handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files) {
      const selectedFiles = Array.from(e.target.files)
      setFiles(prev => [...prev, ...selectedFiles])
    }
  }, [])

  const removeFile = useCallback((index: number) => {
    setFiles(prev => prev.filter((_, i) => i !== index))
  }, [])

  const handleUpload = async () => {
    if (files.length === 0) return

    setUploading(true)
    try {
      for (const file of files) {
        const formData = new FormData()
        formData.append('file', file)
        formData.append('collection', 'bp_nibis_eh')

        // Note: This endpoint needs to be implemented in the backend
        await fetch(`${API_BASE}/api/v1/admin/rag/upload`, {
          method: 'POST',
          body: formData,
        })
      }

      setFiles([])
      onUploadComplete()
    } catch (err) {
      console.error('Upload failed:', err)
    } finally {
      setUploading(false)
    }
  }

  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-lg font-semibold text-slate-900">Dokumente hochladen</h2>
        <p className="text-sm text-slate-500">
          ZIP-Archive oder einzelne PDFs hochladen. ZIPs werden automatisch entpackt.
        </p>
      </div>

      {/* Collection Selector */}
      <div>
        <label className="block text-sm font-medium text-slate-700 mb-2">
          Ziel-Sammlung
        </label>
        <select className="w-full md:w-64 px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500">
          <option value="bp_nibis_eh">Niedersachsen - Klausurkorrektur</option>
          <option value="bp_ni_zeugnis" disabled>Niedersachsen - Zeugnisgenerator (demnächst)</option>
        </select>
      </div>

      {/* Drop Zone */}
      <div
        onDragOver={(e) => { e.preventDefault(); setIsDragging(true) }}
        onDragLeave={() => setIsDragging(false)}
        onDrop={handleDrop}
        className={`
          border-2 border-dashed rounded-lg p-12 text-center transition-colors
          ${isDragging
            ? 'border-primary-500 bg-primary-50'
            : 'border-slate-300 hover:border-slate-400'
          }
        `}
      >
        <svg className="w-12 h-12 text-slate-400 mx-auto mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
          <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>
        <p className="text-lg font-medium text-slate-700 mb-2">
          ZIP-Datei oder Ordner hierher ziehen
        </p>
        <p className="text-sm text-slate-500 mb-4">
          oder
        </p>
        <label className="cursor-pointer">
          <span className="px-4 py-2 bg-white border border-slate-300 rounded-lg text-sm font-medium text-slate-700 hover:bg-slate-50">
            Dateien auswählen
          </span>
          <input
            type="file"
            multiple
            accept=".zip,.pdf"
            onChange={handleFileSelect}
            className="hidden"
          />
        </label>
        <p className="text-xs text-slate-400 mt-4">
          Unterstützt: .zip, .pdf
        </p>
      </div>

      {/* File Queue */}
      {files.length > 0 && (
        <div className="space-y-3">
          <h3 className="text-sm font-medium text-slate-700">Upload-Queue ({files.length})</h3>
          {files.map((file, index) => (
            <div
              key={index}
              className="flex items-center justify-between bg-slate-50 rounded-lg p-3"
            >
              <div className="flex items-center gap-3">
                <svg className="w-5 h-5 text-slate-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                </svg>
                <div>
                  <p className="text-sm font-medium text-slate-900">{file.name}</p>
                  <p className="text-xs text-slate-500">
                    {(file.size / 1024 / 1024).toFixed(2)} MB
                  </p>
                </div>
              </div>
              <button
                onClick={() => removeFile(index)}
                className="p-1 text-slate-400 hover:text-red-500"
              >
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </div>
          ))}

          <button
            onClick={handleUpload}
            disabled={uploading}
            className="w-full py-3 bg-primary-600 text-white rounded-lg font-medium hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
          >
            {uploading ? (
              <>
                <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
                Wird hochgeladen...
              </>
            ) : (
              <>
                <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" />
                </svg>
                Hochladen & Indexieren
              </>
            )}
          </button>
        </div>
      )}
    </div>
  )
}

// ============================================================================
// Ingestion Tab
// ============================================================================

function IngestionTab({
  status,
  onRefresh
}: {
  status: IngestionStatus | null
  onRefresh: () => void
}) {
  const [starting, setStarting] = useState(false)

  const startIngestion = async () => {
    setStarting(true)
    try {
      await fetch(`${API_BASE}/api/v1/admin/nibis/ingest`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ ewh_only: true }),
      })
      onRefresh()
    } catch (err) {
      console.error('Failed to start ingestion:', err)
    } finally {
      setStarting(false)
    }
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-lg font-semibold text-slate-900">Ingestion Status</h2>
          <p className="text-sm text-slate-500">
            Übersicht über laufende und vergangene Indexierungsvorgänge
          </p>
        </div>
        <div className="flex gap-3">
          <button
            onClick={onRefresh}
            className="px-4 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50"
          >
            Aktualisieren
          </button>
          <button
            onClick={startIngestion}
            disabled={status?.running || starting}
            className="px-4 py-2 text-sm font-medium text-white bg-primary-600 rounded-lg hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed"
          >
            {starting ? 'Startet...' : 'Ingestion starten'}
          </button>
        </div>
      </div>

      {/* Current Status */}
      <div className="bg-white rounded-lg border border-slate-200 p-6">
        <div className="flex items-center gap-4 mb-4">
          {status?.running ? (
            <div className="w-3 h-3 bg-yellow-500 rounded-full animate-pulse"></div>
          ) : (
            <div className="w-3 h-3 bg-green-500 rounded-full"></div>
          )}
          <span className="text-lg font-medium text-slate-900">
            {status?.running ? 'Indexierung läuft...' : 'Bereit'}
          </span>
        </div>

        {status && (
          <div className="grid grid-cols-2 md:grid-cols-4 gap-6">
            <div>
              <p className="text-xs text-slate-500 uppercase tracking-wider">Letzte Ausführung</p>
              <p className="text-lg font-semibold text-slate-900">
                {status.lastRun
                  ? new Date(status.lastRun).toLocaleString('de-DE')
                  : '-'
                }
              </p>
            </div>
            <div>
              <p className="text-xs text-slate-500 uppercase tracking-wider">Dokumente</p>
              <p className="text-lg font-semibold text-slate-900">
                {status.documentsIndexed ?? '-'}
              </p>
            </div>
            <div>
              <p className="text-xs text-slate-500 uppercase tracking-wider">Chunks</p>
              <p className="text-lg font-semibold text-slate-900">
                {status.chunksCreated ?? '-'}
              </p>
            </div>
            <div>
              <p className="text-xs text-slate-500 uppercase tracking-wider">Fehler</p>
              <p className={`text-lg font-semibold ${status.errors.length > 0 ? 'text-red-600' : 'text-slate-900'}`}>
                {status.errors.length}
              </p>
            </div>
          </div>
        )}

        {status?.errors && status.errors.length > 0 && (
          <div className="mt-4 p-4 bg-red-50 rounded-lg">
            <h4 className="text-sm font-medium text-red-800 mb-2">Fehler</h4>
            <ul className="text-sm text-red-700 space-y-1">
              {status.errors.slice(0, 5).map((error, i) => (
                <li key={i}>{error}</li>
              ))}
              {status.errors.length > 5 && (
                <li className="text-red-500">... und {status.errors.length - 5} weitere</li>
              )}
            </ul>
          </div>
        )}
      </div>
    </div>
  )
}

// ============================================================================
// Search Tab
// ============================================================================

function SearchTab({ collections }: { collections: Collection[] }) {
  const [query, setQuery] = useState('')
  const [subject, setSubject] = useState<string>('')
  const [year, setYear] = useState<string>('')
  const [results, setResults] = useState<SearchResult[]>([])
  const [searching, setSearching] = useState(false)
  const [latency, setLatency] = useState<number | null>(null)
  const [ratings, setRatings] = useState<Record<string, number>>({})

  const submitRating = async (resultId: string, rating: number) => {
    setRatings(prev => ({ ...prev, [resultId]: rating }))
    try {
      const formData = new FormData()
      formData.append('result_id', resultId)
      formData.append('rating', rating.toString())

      await fetch(`${API_BASE}/api/v1/admin/rag/search/feedback`, {
        method: 'POST',
        body: formData,
      })
    } catch (err) {
      console.error('Failed to submit rating:', err)
    }
  }

  const handleSearch = async () => {
    if (!query.trim()) return

    setSearching(true)
    const startTime = Date.now()

    try {
      const res = await fetch(`${API_BASE}/api/v1/admin/nibis/search`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          query: query.trim(),
          subject: subject || undefined,
          year: year ? parseInt(year) : undefined,
          limit: 10,
        }),
      })

      if (res.ok) {
        const data = await res.json()
        setResults(data)
        setLatency(Date.now() - startTime)
      }
    } catch (err) {
      console.error('Search failed:', err)
    } finally {
      setSearching(false)
    }
  }

  // Get unique subjects from collections
  const subjects = collections.flatMap(c => c.subjects).filter((v, i, a) => a.indexOf(v) === i).sort()
  const years = collections.flatMap(c => c.years).filter((v, i, a) => a.indexOf(v) === i).sort()

  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-lg font-semibold text-slate-900">RAG Suche & Qualitätstest</h2>
        <p className="text-sm text-slate-500">
          Testen Sie die semantische Suche und bewerten Sie die Ergebnisqualität
        </p>
      </div>

      {/* Search Form */}
      <div className="bg-white rounded-lg border border-slate-200 p-6">
        <div className="space-y-4">
          <div>
            <label className="block text-sm font-medium text-slate-700 mb-2">
              Suchanfrage
            </label>
            <input
              type="text"
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              onKeyDown={(e) => e.key === 'Enter' && handleSearch()}
              placeholder="z.B. Analyse eines Gedichts von Rilke"
              className="w-full px-4 py-3 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-primary-500"
            />
          </div>

          <div className="flex flex-wrap gap-4">
            <div className="w-48">
              <label className="block text-sm font-medium text-slate-700 mb-2">
                Fach
              </label>
              <select
                value={subject}
                onChange={(e) => setSubject(e.target.value)}
                className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500"
              >
                <option value="">Alle Fächer</option>
                {subjects.map((s) => (
                  <option key={s} value={s}>{s}</option>
                ))}
              </select>
            </div>

            <div className="w-32">
              <label className="block text-sm font-medium text-slate-700 mb-2">
                Jahr
              </label>
              <select
                value={year}
                onChange={(e) => setYear(e.target.value)}
                className="w-full px-3 py-2 border border-slate-300 rounded-lg focus:ring-2 focus:ring-primary-500"
              >
                <option value="">Alle Jahre</option>
                {years.map((y) => (
                  <option key={y} value={y}>{y}</option>
                ))}
              </select>
            </div>

            <div className="flex items-end">
              <button
                onClick={handleSearch}
                disabled={searching || !query.trim()}
                className="px-6 py-2 bg-primary-600 text-white rounded-lg font-medium hover:bg-primary-700 disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
              >
                {searching ? (
                  <div className="animate-spin rounded-full h-4 w-4 border-b-2 border-white"></div>
                ) : (
                  <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
                  </svg>
                )}
                Suchen
              </button>
            </div>
          </div>
        </div>
      </div>

      {/* Results */}
      {results.length > 0 && (
        <div className="space-y-4">
          <div className="flex items-center justify-between">
            <h3 className="text-sm font-medium text-slate-700">
              {results.length} Ergebnisse
            </h3>
            {latency && (
              <span className="text-sm text-slate-500">
                Latenz: {latency}ms
              </span>
            )}
          </div>

          {results.map((result, index) => (
            <div
              key={result.id}
              className="bg-white rounded-lg border border-slate-200 p-4"
            >
              <div className="flex items-start justify-between mb-2">
                <div className="flex items-center gap-3">
                  <span className="text-lg font-bold text-slate-400">#{index + 1}</span>
                  <span className="px-2 py-1 bg-primary-100 text-primary-700 text-sm rounded font-mono">
                    Score: {result.score.toFixed(3)}
                  </span>
                </div>
                <div className="flex gap-2">
                  {result.year && (
                    <span className="px-2 py-1 bg-slate-100 text-slate-700 text-xs rounded">
                      {result.year}
                    </span>
                  )}
                  {result.subject && (
                    <span className="px-2 py-1 bg-slate-100 text-slate-700 text-xs rounded">
                      {result.subject}
                    </span>
                  )}
                  {result.niveau && (
                    <span className="px-2 py-1 bg-slate-100 text-slate-700 text-xs rounded">
                      {result.niveau}
                    </span>
                  )}
                </div>
              </div>
              <p className="text-sm text-slate-700 leading-relaxed">
                {result.text}
              </p>

              {/* Rating */}
              <div className="mt-4 pt-4 border-t border-slate-100 flex items-center gap-4">
                <span className="text-sm text-slate-500">Relevanz:</span>
                <div className="flex gap-1">
                  {[1, 2, 3, 4, 5].map((starRating) => (
                    <button
                      key={starRating}
                      onClick={() => submitRating(result.id, starRating)}
                      className={`p-1 transition-colors ${
                        (ratings[result.id] || 0) >= starRating
                          ? 'text-yellow-500'
                          : 'text-slate-300 hover:text-yellow-400'
                      }`}
                      title={`${starRating} Sterne`}
                    >
                      <svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
                        <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
                      </svg>
                    </button>
                  ))}
                </div>
                {ratings[result.id] && (
                  <span className="text-xs text-green-600">Bewertet</span>
                )}
              </div>
            </div>
          ))}
        </div>
      )}

      {results.length === 0 && query && !searching && (
        <div className="bg-slate-50 rounded-lg p-8 text-center">
          <p className="text-slate-500">Keine Ergebnisse gefunden</p>
        </div>
      )}
    </div>
  )
}

// ============================================================================
// Metrics Tab
// ============================================================================

function MetricsTab({ collections }: { collections: Collection[] }) {
  const [metrics, setMetrics] = useState({
    precision: 0,
    recall: 0,
    mrr: 0,
    avgLatency: 0,
    totalRatings: 0,
    errorRate: 0,
    scoreDistribution: { '0.9+': 0, '0.7-0.9': 0, '0.5-0.7': 0, '<0.5': 0 },
  })
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    const fetchMetrics = async () => {
      try {
        const res = await fetch(`${API_BASE}/api/v1/admin/rag/metrics`)
        if (res.ok) {
          const data = await res.json()
          setMetrics({
            precision: data.precision_at_5 || 0,
            recall: data.recall_at_10 || 0,
            mrr: data.mrr || 0,
            avgLatency: data.avg_latency_ms || 0,
            totalRatings: data.total_ratings || 0,
            errorRate: data.error_rate || 0,
            scoreDistribution: data.score_distribution || {},
          })
        }
      } catch (err) {
        console.error('Failed to fetch metrics:', err)
      } finally {
        setLoading(false)
      }
    }
    fetchMetrics()
  }, [])

  return (
    <div className="space-y-6">
      <div>
        <h2 className="text-lg font-semibold text-slate-900">RAG Qualitätsmetriken</h2>
        <p className="text-sm text-slate-500">
          Übersicht über Retrieval-Performance und Nutzerbewertungen
        </p>
      </div>

      {/* Metric Cards */}
      <div className="grid grid-cols-2 md:grid-cols-3 gap-4">
        <MetricCard
          title="Precision@5"
          value={`${(metrics.precision * 100).toFixed(0)}%`}
          change="+5%"
          positive
        />
        <MetricCard
          title="Recall@10"
          value={`${(metrics.recall * 100).toFixed(0)}%`}
          change="+3%"
          positive
        />
        <MetricCard
          title="MRR"
          value={metrics.mrr.toFixed(2)}
          change="-2%"
          positive={false}
        />
        <MetricCard
          title="Avg. Latenz"
          value={`${metrics.avgLatency}ms`}
        />
        <MetricCard
          title="Bewertungen"
          value={metrics.totalRatings.toString()}
        />
        <MetricCard
          title="Fehlerrate"
          value={`${metrics.errorRate}%`}
        />
      </div>

      {/* Score Distribution */}
      <div className="bg-white rounded-lg border border-slate-200 p-6">
        <h3 className="text-sm font-medium text-slate-700 mb-4">Score-Verteilung</h3>
        {loading ? (
          <div className="flex justify-center py-4">
            <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-primary-600"></div>
          </div>
        ) : (
          <div className="space-y-3">
            <ScoreBar label="0.9+" percent={metrics.scoreDistribution['0.9+'] || 0} color="bg-green-500" />
            <ScoreBar label="0.7-0.9" percent={metrics.scoreDistribution['0.7-0.9'] || 0} color="bg-green-400" />
            <ScoreBar label="0.5-0.7" percent={metrics.scoreDistribution['0.5-0.7'] || 0} color="bg-yellow-400" />
            <ScoreBar label="<0.5" percent={metrics.scoreDistribution['<0.5'] || 0} color="bg-red-400" />
          </div>
        )}
      </div>

      {/* Export */}
      <div className="flex gap-4">
        <button className="px-4 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50">
          Export CSV
        </button>
        <button className="px-4 py-2 text-sm font-medium text-slate-700 bg-white border border-slate-300 rounded-lg hover:bg-slate-50">
          Detailbericht
        </button>
      </div>
    </div>
  )
}

function MetricCard({
  title,
  value,
  change,
  positive
}: {
  title: string
  value: string
  change?: string
  positive?: boolean
}) {
  return (
    <div className="bg-white rounded-lg border border-slate-200 p-4">
      <p className="text-xs text-slate-500 uppercase tracking-wider mb-1">{title}</p>
      <div className="flex items-end gap-2">
        <p className="text-2xl font-bold text-slate-900">{value}</p>
        {change && (
          <span className={`text-sm font-medium ${positive ? 'text-green-600' : 'text-red-600'}`}>
            {change}
          </span>
        )}
      </div>
    </div>
  )
}

function ScoreBar({ label, percent, color }: { label: string; percent: number; color: string }) {
  return (
    <div className="flex items-center gap-4">
      <span className="text-sm text-slate-600 w-16">{label}</span>
      <div className="flex-1 h-4 bg-slate-100 rounded-full overflow-hidden">
        <div
          className={`h-full ${color} transition-all`}
          style={{ width: `${percent}%` }}
        />
      </div>
      <span className="text-sm text-slate-500 w-12 text-right">{percent}%</span>
    </div>
  )
}
