'use client'

/**
 * DSFA Document Manager
 *
 * Manages DSFA-related sources and documents for the RAG pipeline.
 * Features:
 * - View all registered DSFA sources with license info
 * - Upload new documents
 * - Trigger re-indexing
 * - View corpus statistics
 */

import { useState, useEffect } from 'react'
import Link from 'next/link'
import {
  ArrowLeft,
  RefreshCw,
  Upload,
  FileText,
  Database,
  Scale,
  ExternalLink,
  ChevronDown,
  ChevronUp,
  Search,
  Filter,
  CheckCircle,
  Clock,
  AlertCircle,
  BookOpen
} from 'lucide-react'
import {
  DSFASource,
  DSFACorpusStats,
  DSFASourceStats,
  DSFALicenseCode,
  DSFA_LICENSE_LABELS,
  DSFA_DOCUMENT_TYPE_LABELS
} from '@/lib/sdk/types'

// ============================================================================
// TYPES
// ============================================================================

interface APIError {
  message: string
  status?: number
}

// ============================================================================
// API FUNCTIONS
// ============================================================================

const API_BASE = process.env.NEXT_PUBLIC_KLAUSUR_SERVICE_URL || 'http://localhost:8086'

async function fetchSources(): Promise<DSFASource[]> {
  try {
    const response = await fetch(`${API_BASE}/api/v1/dsfa-rag/sources`)
    if (!response.ok) throw new Error('Failed to fetch sources')
    return await response.json()
  } catch {
    // Return mock data for demo
    return MOCK_SOURCES
  }
}

async function fetchStats(): Promise<DSFACorpusStats> {
  try {
    const response = await fetch(`${API_BASE}/api/v1/dsfa-rag/stats`)
    if (!response.ok) throw new Error('Failed to fetch stats')
    return await response.json()
  } catch {
    return MOCK_STATS
  }
}

async function initializeCorpus(): Promise<{ sources_registered: number }> {
  const response = await fetch(`${API_BASE}/api/v1/dsfa-rag/init`, {
    method: 'POST',
  })
  if (!response.ok) throw new Error('Failed to initialize corpus')
  return await response.json()
}

async function triggerIngestion(sourceCode: string): Promise<void> {
  const response = await fetch(`${API_BASE}/api/v1/dsfa-rag/sources/${sourceCode}/ingest`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({}),
  })
  if (!response.ok) throw new Error('Failed to trigger ingestion')
}

// ============================================================================
// MOCK DATA
// ============================================================================

const MOCK_SOURCES: DSFASource[] = [
  {
    id: '1',
    sourceCode: 'WP248',
    name: 'WP248 rev.01 - Leitlinien zur DSFA',
    fullName: 'Leitlinien zur Datenschutz-Folgenabschaetzung',
    organization: 'Artikel-29-Datenschutzgruppe / EDPB',
    sourceUrl: 'https://ec.europa.eu/newsroom/article29/items/611236/en',
    licenseCode: 'EDPB-LICENSE',
    licenseName: 'EDPB Document License',
    attributionRequired: true,
    attributionText: 'Quelle: WP248 rev.01, Artikel-29-Datenschutzgruppe (2017)',
    documentType: 'guideline',
    language: 'de',
  },
  {
    id: '2',
    sourceCode: 'DSK_KP5',
    name: 'Kurzpapier Nr. 5 - DSFA nach Art. 35 DS-GVO',
    organization: 'Datenschutzkonferenz (DSK)',
    sourceUrl: 'https://www.datenschutzkonferenz-online.de/media/kp/dsk_kpnr_5.pdf',
    licenseCode: 'DL-DE-BY-2.0',
    licenseName: 'Datenlizenz DE – Namensnennung 2.0',
    licenseUrl: 'https://www.govdata.de/dl-de/by-2-0',
    attributionRequired: true,
    attributionText: 'Quelle: DSK Kurzpapier Nr. 5 (Stand: 2018)',
    documentType: 'guideline',
    language: 'de',
  },
  {
    id: '3',
    sourceCode: 'BFDI_MUSS_PUBLIC',
    name: 'BfDI DSFA-Liste (oeffentlicher Bereich)',
    organization: 'BfDI',
    sourceUrl: 'https://www.bfdi.bund.de',
    licenseCode: 'DL-DE-ZERO-2.0',
    licenseName: 'Datenlizenz DE – Zero 2.0',
    attributionRequired: false,
    attributionText: 'Quelle: BfDI, Liste gem. Art. 35 Abs. 4 DSGVO',
    documentType: 'checklist',
    language: 'de',
  },
  {
    id: '4',
    sourceCode: 'NI_MUSS_PRIVATE',
    name: 'LfD NI DSFA-Liste (nicht-oeffentlich)',
    organization: 'LfD Niedersachsen',
    sourceUrl: 'https://www.lfd.niedersachsen.de/download/131098',
    licenseCode: 'DL-DE-BY-2.0',
    licenseName: 'Datenlizenz DE – Namensnennung 2.0',
    attributionRequired: true,
    attributionText: 'Quelle: LfD Niedersachsen, DSFA-Muss-Liste',
    documentType: 'checklist',
    language: 'de',
  },
]

const MOCK_STATS: DSFACorpusStats = {
  sources: [
    {
      sourceId: '1',
      sourceCode: 'WP248',
      name: 'WP248 rev.01',
      organization: 'EDPB',
      licenseCode: 'EDPB-LICENSE',
      documentType: 'guideline',
      documentCount: 1,
      chunkCount: 50,
      lastIndexedAt: '2026-02-09T10:00:00Z',
    },
    {
      sourceId: '2',
      sourceCode: 'DSK_KP5',
      name: 'DSK Kurzpapier Nr. 5',
      organization: 'DSK',
      licenseCode: 'DL-DE-BY-2.0',
      documentType: 'guideline',
      documentCount: 1,
      chunkCount: 35,
      lastIndexedAt: '2026-02-09T10:00:00Z',
    },
  ],
  totalSources: 45,
  totalDocuments: 45,
  totalChunks: 850,
  qdrantCollection: 'bp_dsfa_corpus',
  qdrantPointsCount: 850,
  qdrantStatus: 'green',
}

// ============================================================================
// COMPONENTS
// ============================================================================

function LicenseBadge({ licenseCode }: { licenseCode: DSFALicenseCode }) {
  const colorMap: Record<DSFALicenseCode, string> = {
    'DL-DE-BY-2.0': 'bg-blue-100 text-blue-700 border-blue-200',
    'DL-DE-ZERO-2.0': 'bg-gray-100 text-gray-700 border-gray-200',
    'CC-BY-4.0': 'bg-green-100 text-green-700 border-green-200',
    'EDPB-LICENSE': 'bg-purple-100 text-purple-700 border-purple-200',
    'PUBLIC_DOMAIN': 'bg-gray-100 text-gray-600 border-gray-200',
    'PROPRIETARY': 'bg-amber-100 text-amber-700 border-amber-200',
  }

  return (
    <span className={`inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs border ${colorMap[licenseCode] || 'bg-gray-100 text-gray-700 border-gray-200'}`}>
      <Scale className="w-3 h-3" />
      {DSFA_LICENSE_LABELS[licenseCode] || licenseCode}
    </span>
  )
}

function DocumentTypeBadge({ type }: { type?: string }) {
  if (!type) return null

  const colorMap: Record<string, string> = {
    guideline: 'bg-indigo-100 text-indigo-700',
    checklist: 'bg-emerald-100 text-emerald-700',
    regulation: 'bg-red-100 text-red-700',
    template: 'bg-orange-100 text-orange-700',
  }

  return (
    <span className={`inline-flex items-center px-2 py-0.5 rounded text-xs ${colorMap[type] || 'bg-gray-100 text-gray-700'}`}>
      {DSFA_DOCUMENT_TYPE_LABELS[type as keyof typeof DSFA_DOCUMENT_TYPE_LABELS] || type}
    </span>
  )
}

function StatusIndicator({ status }: { status: string }) {
  const statusConfig: Record<string, { color: string; icon: React.ReactNode; label: string }> = {
    green: { color: 'text-green-500', icon: <CheckCircle className="w-4 h-4" />, label: 'Aktiv' },
    yellow: { color: 'text-yellow-500', icon: <Clock className="w-4 h-4" />, label: 'Ausstehend' },
    red: { color: 'text-red-500', icon: <AlertCircle className="w-4 h-4" />, label: 'Fehler' },
  }

  const config = statusConfig[status] || statusConfig.yellow

  return (
    <span className={`inline-flex items-center gap-1 ${config.color}`}>
      {config.icon}
      <span className="text-sm">{config.label}</span>
    </span>
  )
}

function SourceCard({
  source,
  stats,
  onIngest,
  isIngesting
}: {
  source: DSFASource
  stats?: DSFASourceStats
  onIngest: () => void
  isIngesting: boolean
}) {
  const [isExpanded, setIsExpanded] = useState(false)

  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 overflow-hidden">
      <div className="p-4">
        <div className="flex items-start justify-between">
          <div className="flex-1 min-w-0">
            <div className="flex items-center gap-2 mb-1">
              <span className="font-mono text-xs bg-gray-100 dark:bg-gray-700 px-2 py-0.5 rounded">
                {source.sourceCode}
              </span>
              <DocumentTypeBadge type={source.documentType} />
            </div>
            <h3 className="font-semibold text-gray-900 dark:text-white truncate">
              {source.name}
            </h3>
            {source.organization && (
              <p className="text-sm text-gray-500 dark:text-gray-400">
                {source.organization}
              </p>
            )}
          </div>
          <button
            onClick={() => setIsExpanded(!isExpanded)}
            className="p-1 hover:bg-gray-100 dark:hover:bg-gray-700 rounded"
          >
            {isExpanded ? (
              <ChevronUp className="w-5 h-5 text-gray-400" />
            ) : (
              <ChevronDown className="w-5 h-5 text-gray-400" />
            )}
          </button>
        </div>

        <div className="flex items-center gap-4 mt-3">
          <LicenseBadge licenseCode={source.licenseCode} />
          {stats && (
            <>
              <span className="text-sm text-gray-500">
                {stats.documentCount} Dok.
              </span>
              <span className="text-sm text-gray-500">
                {stats.chunkCount} Chunks
              </span>
            </>
          )}
        </div>

        {source.attributionRequired && (
          <div className="mt-3 p-2 bg-amber-50 dark:bg-amber-900/20 rounded text-xs text-amber-700 dark:text-amber-300">
            <strong>Attribution:</strong> {source.attributionText}
          </div>
        )}
      </div>

      {isExpanded && (
        <div className="border-t border-gray-200 dark:border-gray-700 p-4 bg-gray-50 dark:bg-gray-900">
          <dl className="grid grid-cols-2 gap-3 text-sm">
            {source.sourceUrl && (
              <>
                <dt className="text-gray-500">Quelle:</dt>
                <dd>
                  <a
                    href={source.sourceUrl}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="text-blue-600 hover:underline flex items-center gap-1"
                  >
                    Link <ExternalLink className="w-3 h-3" />
                  </a>
                </dd>
              </>
            )}
            {source.licenseUrl && (
              <>
                <dt className="text-gray-500">Lizenz-URL:</dt>
                <dd>
                  <a
                    href={source.licenseUrl}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="text-blue-600 hover:underline flex items-center gap-1"
                  >
                    {source.licenseName} <ExternalLink className="w-3 h-3" />
                  </a>
                </dd>
              </>
            )}
            <dt className="text-gray-500">Sprache:</dt>
            <dd className="uppercase">{source.language}</dd>
            {stats?.lastIndexedAt && (
              <>
                <dt className="text-gray-500">Zuletzt indexiert:</dt>
                <dd>{new Date(stats.lastIndexedAt).toLocaleString('de-DE')}</dd>
              </>
            )}
          </dl>

          <div className="mt-4 flex gap-2">
            <button
              onClick={onIngest}
              disabled={isIngesting}
              className="px-3 py-1.5 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 flex items-center gap-1"
            >
              {isIngesting ? (
                <RefreshCw className="w-4 h-4 animate-spin" />
              ) : (
                <RefreshCw className="w-4 h-4" />
              )}
              Neu indexieren
            </button>
          </div>
        </div>
      )}
    </div>
  )
}

function StatsOverview({ stats }: { stats: DSFACorpusStats }) {
  return (
    <div className="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-6">
      <div className="flex items-center justify-between mb-4">
        <h2 className="text-lg font-semibold text-gray-900 dark:text-white flex items-center gap-2">
          <Database className="w-5 h-5" />
          Corpus-Statistik
        </h2>
        <StatusIndicator status={stats.qdrantStatus} />
      </div>

      <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
        <div className="text-center p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg">
          <p className="text-2xl font-bold text-blue-600 dark:text-blue-400">
            {stats.totalSources}
          </p>
          <p className="text-sm text-gray-600 dark:text-gray-400">Quellen</p>
        </div>
        <div className="text-center p-4 bg-emerald-50 dark:bg-emerald-900/20 rounded-lg">
          <p className="text-2xl font-bold text-emerald-600 dark:text-emerald-400">
            {stats.totalDocuments}
          </p>
          <p className="text-sm text-gray-600 dark:text-gray-400">Dokumente</p>
        </div>
        <div className="text-center p-4 bg-purple-50 dark:bg-purple-900/20 rounded-lg">
          <p className="text-2xl font-bold text-purple-600 dark:text-purple-400">
            {stats.totalChunks.toLocaleString()}
          </p>
          <p className="text-sm text-gray-600 dark:text-gray-400">Chunks</p>
        </div>
        <div className="text-center p-4 bg-orange-50 dark:bg-orange-900/20 rounded-lg">
          <p className="text-2xl font-bold text-orange-600 dark:text-orange-400">
            {stats.qdrantPointsCount.toLocaleString()}
          </p>
          <p className="text-sm text-gray-600 dark:text-gray-400">Vektoren</p>
        </div>
      </div>

      <div className="mt-4 p-3 bg-gray-50 dark:bg-gray-900 rounded-lg">
        <p className="text-sm text-gray-600 dark:text-gray-400">
          <strong>Collection:</strong>{' '}
          <code className="font-mono bg-gray-200 dark:bg-gray-700 px-1 rounded">
            {stats.qdrantCollection}
          </code>
        </p>
      </div>
    </div>
  )
}

// ============================================================================
// MAIN PAGE
// ============================================================================

export default function DSFADocumentManagerPage() {
  const [sources, setSources] = useState<DSFASource[]>([])
  const [stats, setStats] = useState<DSFACorpusStats | null>(null)
  const [isLoading, setIsLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [searchQuery, setSearchQuery] = useState('')
  const [filterType, setFilterType] = useState<string>('all')
  const [ingestingSource, setIngestingSource] = useState<string | null>(null)
  const [isInitializing, setIsInitializing] = useState(false)

  useEffect(() => {
    async function loadData() {
      setIsLoading(true)
      try {
        const [sourcesData, statsData] = await Promise.all([
          fetchSources(),
          fetchStats(),
        ])
        setSources(sourcesData)
        setStats(statsData)
        setError(null)
      } catch (err) {
        setError(err instanceof Error ? err.message : 'Failed to load data')
        setSources(MOCK_SOURCES)
        setStats(MOCK_STATS)
      } finally {
        setIsLoading(false)
      }
    }
    loadData()
  }, [])

  const handleInitialize = async () => {
    setIsInitializing(true)
    try {
      await initializeCorpus()
      // Reload data
      const [sourcesData, statsData] = await Promise.all([
        fetchSources(),
        fetchStats(),
      ])
      setSources(sourcesData)
      setStats(statsData)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to initialize')
    } finally {
      setIsInitializing(false)
    }
  }

  const handleIngest = async (sourceCode: string) => {
    setIngestingSource(sourceCode)
    try {
      await triggerIngestion(sourceCode)
      // Reload stats
      const statsData = await fetchStats()
      setStats(statsData)
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to ingest')
    } finally {
      setIngestingSource(null)
    }
  }

  // Filter sources
  const filteredSources = sources.filter(source => {
    const matchesSearch = searchQuery === '' ||
      source.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
      source.sourceCode.toLowerCase().includes(searchQuery.toLowerCase()) ||
      source.organization?.toLowerCase().includes(searchQuery.toLowerCase())

    const matchesType = filterType === 'all' || source.documentType === filterType

    return matchesSearch && matchesType
  })

  // Get stats by source code
  const getStatsForSource = (sourceCode: string): DSFASourceStats | undefined => {
    return stats?.sources.find(s => s.sourceCode === sourceCode)
  }

  return (
    <div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800 p-8">
      <div className="max-w-6xl mx-auto">
        {/* Header */}
        <div className="mb-8">
          <Link
            href="/ai/rag-pipeline"
            className="inline-flex items-center gap-2 text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white mb-4"
          >
            <ArrowLeft className="w-4 h-4" />
            Zurueck zur RAG-Pipeline
          </Link>

          <div className="flex justify-between items-start">
            <div>
              <h1 className="text-3xl font-bold text-gray-900 dark:text-white flex items-center gap-3">
                <BookOpen className="w-8 h-8 text-blue-600" />
                DSFA-Quellen Manager
              </h1>
              <p className="text-gray-500 dark:text-gray-400 mt-1">
                Verwalten Sie DSFA-Guidance Dokumente mit vollstaendiger Lizenzattribution
              </p>
            </div>

            <div className="flex gap-2">
              <button
                onClick={handleInitialize}
                disabled={isInitializing}
                className="px-4 py-2 bg-emerald-600 text-white rounded-lg hover:bg-emerald-700 disabled:opacity-50 flex items-center gap-2"
              >
                {isInitializing ? (
                  <RefreshCw className="w-4 h-4 animate-spin" />
                ) : (
                  <Database className="w-4 h-4" />
                )}
                Initialisieren
              </button>
              <button className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 flex items-center gap-2">
                <Upload className="w-4 h-4" />
                Dokument hochladen
              </button>
            </div>
          </div>
        </div>

        {/* Error Banner */}
        {error && (
          <div className="mb-6 p-4 bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-700 rounded-xl">
            <div className="flex items-center gap-3">
              <AlertCircle className="w-5 h-5 text-red-500" />
              <span className="text-red-800 dark:text-red-200">{error}</span>
              <button
                onClick={() => setError(null)}
                className="ml-auto text-red-600 hover:text-red-800"
              >
                &times;
              </button>
            </div>
          </div>
        )}

        {/* Stats Overview */}
        {stats && <StatsOverview stats={stats} />}

        {/* Search & Filter */}
        <div className="mt-6 flex gap-4">
          <div className="flex-1 relative">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-5 h-5 text-gray-400" />
            <input
              type="text"
              placeholder="Quellen durchsuchen..."
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="w-full pl-10 pr-4 py-2 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800"
            />
          </div>
          <div className="relative">
            <Filter className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
            <select
              value={filterType}
              onChange={(e) => setFilterType(e.target.value)}
              className="pl-9 pr-8 py-2 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800 appearance-none"
            >
              <option value="all">Alle Typen</option>
              <option value="guideline">Leitlinien</option>
              <option value="checklist">Prueflisten</option>
              <option value="regulation">Verordnungen</option>
            </select>
          </div>
        </div>

        {/* Sources List */}
        <div className="mt-6">
          <div className="flex items-center justify-between mb-4">
            <h2 className="text-lg font-semibold text-gray-900 dark:text-white">
              Registrierte Quellen ({filteredSources.length})
            </h2>
          </div>

          {isLoading ? (
            <div className="flex items-center justify-center py-20">
              <div className="text-center">
                <div className="w-12 h-12 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin mx-auto mb-4" />
                <p className="text-gray-500 dark:text-gray-400">Lade Quellen...</p>
              </div>
            </div>
          ) : filteredSources.length === 0 ? (
            <div className="text-center py-12 bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700">
              <FileText className="w-12 h-12 text-gray-400 mx-auto mb-4" />
              <p className="text-gray-500 dark:text-gray-400">
                {searchQuery || filterType !== 'all'
                  ? 'Keine Quellen gefunden'
                  : 'Noch keine Quellen registriert'}
              </p>
              {!searchQuery && filterType === 'all' && (
                <button
                  onClick={handleInitialize}
                  className="mt-4 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
                >
                  Quellen initialisieren
                </button>
              )}
            </div>
          ) : (
            <div className="grid gap-4">
              {filteredSources.map(source => (
                <SourceCard
                  key={source.id}
                  source={source}
                  stats={getStatsForSource(source.sourceCode)}
                  onIngest={() => handleIngest(source.sourceCode)}
                  isIngesting={ingestingSource === source.sourceCode}
                />
              ))}
            </div>
          )}
        </div>

        {/* Info Box */}
        <div className="mt-8 p-6 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-xl">
          <h3 className="font-semibold text-blue-900 dark:text-blue-100 mb-2">
            Ueber die Lizenzattribution
          </h3>
          <p className="text-sm text-blue-800 dark:text-blue-200 mb-4">
            Alle DSFA-Quellen werden mit vollstaendiger Lizenzinformation gespeichert.
            Bei der Nutzung der RAG-Suche werden automatisch die korrekten Attributionen angezeigt.
          </p>
          <div className="grid grid-cols-2 md:grid-cols-3 gap-3 text-sm">
            <div className="flex items-center gap-2">
              <LicenseBadge licenseCode="DL-DE-BY-2.0" />
              <span className="text-blue-700 dark:text-blue-300">Namensnennung</span>
            </div>
            <div className="flex items-center gap-2">
              <LicenseBadge licenseCode="DL-DE-ZERO-2.0" />
              <span className="text-blue-700 dark:text-blue-300">Keine Attribution</span>
            </div>
            <div className="flex items-center gap-2">
              <LicenseBadge licenseCode="CC-BY-4.0" />
              <span className="text-blue-700 dark:text-blue-300">CC Attribution</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
