'use client'

/**
 * RAG & Legal Corpus Management
 *
 * Verwaltet das Legal Corpus RAG System fuer Compliance.
 * Zeigt Status aller 19 Regulierungen, Chunks und ermoeglicht Suche.
 */

import React, { useState, useEffect, useCallback } from 'react'
import Link from 'next/link'
import { PagePurpose } from '@/components/common/PagePurpose'
import { AIModuleSidebarResponsive } from '@/components/ai/AIModuleSidebar'
import { REGULATIONS_IN_RAG } from './rag-constants'
import { ChunkBrowserQA } from './components/ChunkBrowserQA'

// API uses local proxy route to klausur-service
const API_PROXY = '/api/legal-corpus'
const DSFA_API_PROXY = '/api/dsfa-corpus'

// Types
interface RegulationStatus {
  code: string
  name: string
  fullName: string
  type: string
  chunkCount: number
  expectedRequirements: number
  sourceUrl: string
  status: 'ready' | 'empty' | 'error'
}

interface CollectionStatus {
  collection: string
  totalPoints: number
  vectorSize: number
  status: string
  regulations: Record<string, number>
}

interface SearchResult {
  text: string
  regulation_code: string
  regulation_name: string
  article: string | null
  paragraph: string | null
  source_url: string
  score: number
}

// DSFA source type (from /api/dsfa-corpus)
interface DsfaSource {
  source_code: string
  name: string
  full_name?: string
  organization?: string
  source_url?: string
  license_code: string
  attribution_text: string
  document_type: string
  language: string
  chunk_count?: number
}

interface DsfaCorpusStatus {
  qdrant_collection: string
  total_sources: number
  total_documents: number
  total_chunks: number
  qdrant_points_count: number
  qdrant_status: string
}

// RAG category filter for Regulations tab
type RegulationCategory = 'regulations' | 'dsfa' | 'nibis' | 'templates'

// Tab definitions
type TabId = 'overview' | 'regulations' | 'map' | 'search' | 'chunks' | 'data' | 'ingestion' | 'pipeline'

// Custom document type
interface CustomDocument {
  id: string
  code: string
  title: string
  filename?: string
  url?: string
  document_type: string
  uploaded_at: string
  status: 'uploaded' | 'queued' | 'fetching' | 'processing' | 'indexed' | 'error'
  chunk_count: number
  error?: string
}

// Pipeline types
interface Validation {
  name: string
  status: 'passed' | 'warning' | 'failed' | 'not_run'
  expected: any
  actual: any
  message: string
}

interface PipelineCheckpoint {
  phase: string
  name: string
  status: 'pending' | 'running' | 'completed' | 'failed' | 'skipped'
  started_at: string | null
  completed_at: string | null
  duration_seconds: number | null
  metrics: Record<string, any>
  validations: Validation[]
  error: string | null
}

interface PipelineState {
  status: string
  pipeline_id: string | null
  started_at: string | null
  completed_at: string | null
  current_phase: string | null
  checkpoints: PipelineCheckpoint[]
  summary: Record<string, any>
  validation_summary?: {
    passed: number
    warning: number
    failed: number
    total: number
  }
}

// All regulations with descriptions
const REGULATIONS = [
  {
    code: 'GDPR',
    name: 'DSGVO',
    fullName: 'Datenschutz-Grundverordnung (GDPR)',
    type: 'eu_regulation',
    expected: 99,
    description: 'Die DSGVO ist das zentrale Datenschutzgesetz der EU. Sie regelt die Verarbeitung personenbezogener Daten und gibt Betroffenen umfangreiche Rechte (Auskunft, Loeschung, Datenportabilitaet). Gilt fuer alle Unternehmen, die Daten von EU-Buergern verarbeiten.',
    relevantFor: ['Alle Unternehmen mit EU-Kunden', 'Datenverarbeiter', 'Auftragsverarbeiter'],
    keyTopics: ['Einwilligung', 'Betroffenenrechte', 'Datenschutz-Folgenabschaetzung', 'Auftragsverarbeitung', 'Bussgelder bis 4% Umsatz'],
    effectiveDate: '25. Mai 2018'
  },
  {
    code: 'EPRIVACY',
    name: 'ePrivacy-Richtlinie',
    fullName: 'Richtlinie 2002/58/EG (ePrivacy)',
    type: 'eu_directive',
    expected: 25,
    description: 'Ergaenzt die DSGVO speziell fuer elektronische Kommunikation. Regelt Cookies, Tracking, Direktmarketing und Vertraulichkeit der Kommunikation. Wird durch nationale Gesetze wie das TDDDG umgesetzt.',
    relevantFor: ['Website-Betreiber', 'App-Entwickler', 'Marketing-Abteilungen', 'Telekommunikationsanbieter'],
    keyTopics: ['Cookie-Consent', 'Tracking', 'E-Mail-Marketing', 'Vertraulichkeit'],
    effectiveDate: '31. Juli 2002'
  },
  {
    code: 'TDDDG',
    name: 'TDDDG',
    fullName: 'Telekommunikation-Digitale-Dienste-Datenschutz-Gesetz',
    type: 'de_law',
    expected: 30,
    description: 'Deutsches Umsetzungsgesetz der ePrivacy-Richtlinie. Regelt den Datenschutz bei Telemedien und Telekommunikation. Enthaelt die strengen deutschen Cookie-Consent-Anforderungen.',
    relevantFor: ['Deutsche Unternehmen', 'Website-Betreiber mit deutschen Nutzern', 'App-Anbieter'],
    keyTopics: ['Cookie-Banner', 'Einwilligung fuer Endgeraetezugriff', 'Tracking-Consent', 'Bestandsdaten'],
    effectiveDate: '1. Dezember 2021'
  },
  {
    code: 'SCC',
    name: 'Standardvertragsklauseln',
    fullName: 'EU-Standardvertragsklauseln (2021/914/EU)',
    type: 'eu_regulation',
    expected: 18,
    description: 'Vorgefertigte Vertragsklauseln fuer den internationalen Datentransfer. Erforderlich, wenn personenbezogene Daten in Drittlaender ohne Angemessenheitsbeschluss uebermittelt werden (z.B. USA vor DPF).',
    relevantFor: ['Unternehmen mit Drittland-Transfers', 'Cloud-Nutzer', 'Internationale Konzerne'],
    keyTopics: ['Drittlandtransfer', 'Controller-to-Controller', 'Controller-to-Processor', 'TIA (Transfer Impact Assessment)'],
    effectiveDate: '27. Juni 2021'
  },
  {
    code: 'DPF',
    name: 'EU-US Data Privacy Framework',
    fullName: 'EU-US Data Privacy Framework',
    type: 'eu_regulation',
    expected: 12,
    description: 'Angemessenheitsbeschluss fuer Datentransfers in die USA. Nachfolger des gekippten Privacy Shield. Ermoeglicht Datenuebermittlungen an zertifizierte US-Unternehmen ohne zusaetzliche Garantien.',
    relevantFor: ['Unternehmen mit US-Dienstleistern', 'Cloud-Nutzer (AWS, Google, Microsoft)', 'SaaS-Anwender'],
    keyTopics: ['US-Datentransfer', 'Zertifizierung', 'Redress-Mechanismus', 'Privacy Shield Nachfolger'],
    effectiveDate: '10. Juli 2023'
  },
  {
    code: 'AIACT',
    name: 'EU AI Act',
    fullName: 'Verordnung (EU) 2024/1689 - KI-Verordnung',
    type: 'eu_regulation',
    expected: 85,
    description: 'Weltweit erste umfassende KI-Regulierung. Klassifiziert KI-Systeme nach Risiko (verboten, hoch, begrenzt, minimal) und stellt entsprechende Anforderungen. Hochrisiko-KI benoetigt CE-Kennzeichnung.',
    relevantFor: ['KI-Entwickler', 'KI-Anwender', 'Hersteller von KI-Produkten', 'Importeure'],
    keyTopics: ['Risikoklassifizierung', 'Hochrisiko-KI', 'Verbotene KI', 'Transparenzpflichten', 'CE-Kennzeichnung'],
    effectiveDate: '1. August 2024 (gestaffelt bis 2027)'
  },
  {
    code: 'CRA',
    name: 'Cyber Resilience Act',
    fullName: 'Verordnung (EU) 2024/2847 - Cyber Resilience Act',
    type: 'eu_regulation',
    expected: 45,
    description: 'Cybersicherheitsanforderungen fuer Produkte mit digitalen Elementen. Verpflichtet Hersteller zu Security-by-Design, Schwachstellenmanagement und Security-Updates ueber den Lebenszyklus.',
    relevantFor: ['IoT-Hersteller', 'Software-Entwickler', 'Hardware-Hersteller', 'Importeure'],
    keyTopics: ['Security by Design', 'Schwachstellenmanagement', 'SBOM', 'CE-Kennzeichnung', 'Security Updates'],
    effectiveDate: '2024 (Uebergangsfristen bis 2027)'
  },
  {
    code: 'NIS2',
    name: 'NIS2-Richtlinie',
    fullName: 'Richtlinie (EU) 2022/2555 - Network and Information Security',
    type: 'eu_directive',
    expected: 46,
    description: 'Cybersicherheitsrichtlinie fuer kritische und wichtige Einrichtungen. Erweitert NIS1 erheblich auf mehr Sektoren. Fordert Risikomanagement, Incident Reporting und Lieferkettensicherheit.',
    relevantFor: ['Kritische Infrastrukturen (KRITIS)', 'Gesundheitswesen', 'Energie', 'Transport', 'Digitale Dienste', 'Oeffentliche Verwaltung'],
    keyTopics: ['Cybersicherheits-Risikomanagement', 'Incident Reporting (24h)', 'Lieferkettensicherheit', 'Geschaeftsfuehrer-Haftung'],
    effectiveDate: '17. Oktober 2024 (nationale Umsetzung)'
  },
  {
    code: 'EUCSA',
    name: 'EU Cybersecurity Act',
    fullName: 'Verordnung (EU) 2019/881 - EU Cybersecurity Act',
    type: 'eu_regulation',
    expected: 35,
    description: 'Schafft den EU-Rahmen fuer Cybersicherheitszertifizierung und staerkt die ENISA. Ermoeglicht EU-weite Zertifizierungsschemata fuer IT-Produkte, -Dienste und -Prozesse.',
    relevantFor: ['IT-Produkthersteller', 'Cloud-Anbieter', 'Zertifizierungsstellen', 'Oeffentliche Auftraggeber'],
    keyTopics: ['Cybersicherheitszertifizierung', 'ENISA', 'Vertrauensstufen (basic/substantial/high)', 'EUCC Schema'],
    effectiveDate: '27. Juni 2019'
  },
  {
    code: 'DATAACT',
    name: 'Data Act',
    fullName: 'Verordnung (EU) 2023/2854 - Data Act',
    type: 'eu_regulation',
    expected: 42,
    description: 'Regelt den Zugang zu und die Nutzung von Daten. Gibt Nutzern Rechte an Daten, die durch vernetzte Produkte erzeugt werden. Ermoeglicht Datenweitergabe und Cloud-Wechsel.',
    relevantFor: ['IoT-Hersteller', 'Cloud-Anbieter', 'Dateninhaber', 'Datennutzer', 'Oeffentliche Stellen'],
    keyTopics: ['Datenzugang', 'Datenportabilitaet', 'Cloud-Switching', 'B2B-Datenteilung', 'IoT-Daten'],
    effectiveDate: '12. September 2025'
  },
  {
    code: 'DGA',
    name: 'Data Governance Act',
    fullName: 'Verordnung (EU) 2022/868 - Data Governance Act',
    type: 'eu_regulation',
    expected: 35,
    description: 'Schafft Rahmenbedingungen fuer Datenmaerkte und Datenaltruismus. Regelt Datenvermittlungsdienste und die Weiterverwendung geschuetzter oeffentlicher Daten.',
    relevantFor: ['Datenvermittler', 'Oeffentliche Stellen', 'Forschungseinrichtungen', 'Datenaltruismus-Organisationen'],
    keyTopics: ['Datenvermittlung', 'Datenaltruismus', 'Oeffentliche Daten', 'Datentreuhaender'],
    effectiveDate: '24. September 2023'
  },
  {
    code: 'DSA',
    name: 'Digital Services Act',
    fullName: 'Verordnung (EU) 2022/2065 - Digital Services Act',
    type: 'eu_regulation',
    expected: 93,
    description: 'Reguliert digitale Dienste und Plattformen. Schafft Pflichten fuer Online-Vermittler, Hosting-Dienste und Plattformen. Sehr grosse Plattformen (VLOPs) haben erweiterte Pflichten.',
    relevantFor: ['Online-Plattformen', 'Marktplaetze', 'Social Media', 'Hosting-Anbieter', 'Suchmaschinen'],
    keyTopics: ['Notice-and-Action', 'Transparenz', 'Illegale Inhalte', 'VLOP-Pflichten', 'Algorithmen-Transparenz'],
    effectiveDate: '17. Februar 2024'
  },
  {
    code: 'EAA',
    name: 'European Accessibility Act',
    fullName: 'Richtlinie (EU) 2019/882 - Barrierefreiheitsanforderungen',
    type: 'eu_directive',
    expected: 25,
    description: 'Barrierefreiheitsanforderungen fuer Produkte und Dienstleistungen. Betrifft Computer, Smartphones, Bankdienstleistungen, E-Commerce, E-Books und mehr.',
    relevantFor: ['E-Commerce', 'Banken', 'Telekommunikation', 'Verkehrsdienste', 'Medienanbieter'],
    keyTopics: ['Barrierefreiheit', 'WCAG', 'Assistive Technologien', 'Ausnahmen fuer KMU'],
    effectiveDate: '28. Juni 2025'
  },
  {
    code: 'DSM',
    name: 'DSM-Urheberrechtsrichtlinie',
    fullName: 'Richtlinie (EU) 2019/790 - Digital Single Market Copyright',
    type: 'eu_directive',
    expected: 22,
    description: 'Modernisiert das EU-Urheberrecht fuer das digitale Zeitalter. Enthaelt kontroverse Artikel zu Uploadfiltern (Art. 17) und Leistungsschutzrecht fuer Presseverleger (Art. 15).',
    relevantFor: ['Content-Plattformen', 'Nachrichtenaggregatoren', 'Bildungseinrichtungen', 'Kulturerbe-Einrichtungen'],
    keyTopics: ['Upload-Filter (Art. 17)', 'Leistungsschutzrecht', 'Text-und-Data-Mining', 'Verguetungsansprueche'],
    effectiveDate: '7. Juni 2021'
  },
  {
    code: 'PLD',
    name: 'Produkthaftungsrichtlinie',
    fullName: 'Richtlinie 85/374/EWG (aktualisiert) - Produkthaftung',
    type: 'eu_directive',
    expected: 18,
    description: 'Regelt die Haftung fuer fehlerhafte Produkte. Aktualisierte Version umfasst auch Software und KI. Hersteller haften verschuldensunabhaengig fuer Produktfehler.',
    relevantFor: ['Produkthersteller', 'Software-Entwickler', 'KI-Anbieter', 'Importeure'],
    keyTopics: ['Verschuldensunabhaengige Haftung', 'Software als Produkt', 'KI-Haftung', 'Beweislast'],
    effectiveDate: 'Ueberarbeitung 2024'
  },
  {
    code: 'GPSR',
    name: 'General Product Safety',
    fullName: 'Verordnung (EU) 2023/988 - Allgemeine Produktsicherheit',
    type: 'eu_regulation',
    expected: 30,
    description: 'Ersetzt die alte Produktsicherheitsrichtlinie. Stellt sicher, dass nur sichere Verbraucherprodukte auf den EU-Markt gelangen. Gilt auch fuer Online-Marktplaetze.',
    relevantFor: ['Produkthersteller', 'Importeure', 'Online-Marktplaetze', 'Haendler'],
    keyTopics: ['Produktsicherheit', 'Marktplatzhaftung', 'Rueckrufe', 'Safety Gate'],
    effectiveDate: '13. Dezember 2024'
  },
  {
    code: 'BSI-TR-03161-1',
    name: 'BSI-TR Teil 1',
    fullName: 'BSI TR-03161 Teil 1 - Sicherheitsanforderungen an Digitale Gesundheitsanwendungen (DiGA) - Mobile Anwendungen',
    type: 'bsi_standard',
    expected: 45,
    description: 'Deutsche Technische Richtlinie fuer die Sicherheit mobiler Gesundheits-Apps (DiGA). Definiert Pruefverfahren und Sicherheitsanforderungen fuer die DiGA-Zulassung.',
    relevantFor: ['DiGA-Hersteller', 'Mobile-App-Entwickler im Gesundheitswesen', 'Pruefstellen'],
    keyTopics: ['Mobile App Security', 'Authentifizierung', 'Datenverschluesselung', 'Secure Coding'],
    effectiveDate: 'Version 1.0: 2020'
  },
  {
    code: 'BSI-TR-03161-2',
    name: 'BSI-TR Teil 2',
    fullName: 'BSI TR-03161 Teil 2 - Sicherheitsanforderungen an Digitale Gesundheitsanwendungen (DiGA) - Web-Anwendungen',
    type: 'bsi_standard',
    expected: 40,
    description: 'Technische Richtlinie fuer die Sicherheit von Web-Anwendungen im Gesundheitswesen. Ergaenzt Teil 1 um spezifische Anforderungen fuer Web-Frontends.',
    relevantFor: ['DiGA-Hersteller mit Web-Apps', 'Web-Entwickler im Gesundheitswesen', 'Pruefstellen'],
    keyTopics: ['Web Application Security', 'OWASP Top 10', 'Session Management', 'TLS'],
    effectiveDate: 'Version 1.0: 2020'
  },
  {
    code: 'BSI-TR-03161-3',
    name: 'BSI-TR Teil 3',
    fullName: 'BSI TR-03161 Teil 3 - Sicherheitsanforderungen an Digitale Gesundheitsanwendungen (DiGA) - Hintergrundsysteme',
    type: 'bsi_standard',
    expected: 35,
    description: 'Technische Richtlinie fuer Backend-Systeme von Gesundheitsanwendungen. Deckt Server, APIs, Datenbanken und Cloud-Infrastruktur ab.',
    relevantFor: ['DiGA-Backend-Entwickler', 'Cloud-Architekten im Gesundheitswesen', 'DevOps-Teams'],
    keyTopics: ['Backend Security', 'API Security', 'Datenbanksicherheit', 'Cloud Security', 'Logging'],
    effectiveDate: 'Version 1.0: 2020'
  },
  // Financial Sector Regulations
  {
    code: 'DORA',
    name: 'DORA',
    fullName: 'Verordnung (EU) 2022/2554 - Digital Operational Resilience Act',
    type: 'eu_regulation',
    expected: 64,
    description: 'Digitale operationale Resilienz fuer den Finanzsektor. Verpflichtet Finanzunternehmen zu umfassendem IKT-Risikomanagement, Vorfallmeldung, Resilienz-Tests und Drittanbieter-Management.',
    relevantFor: ['Banken', 'Versicherungen', 'Wertpapierfirmen', 'Zahlungsdienstleister', 'Krypto-Anbieter', 'IKT-Drittanbieter'],
    keyTopics: ['IKT-Risikomanagement', 'Incident Reporting', 'Resilience Testing', 'Third-Party Risk', 'Threat-Led Penetration Testing'],
    effectiveDate: '17. Januar 2025'
  },
  {
    code: 'PSD2',
    name: 'PSD2',
    fullName: 'Richtlinie (EU) 2015/2366 - Zahlungsdiensterichtlinie',
    type: 'eu_directive',
    expected: 117,
    description: 'Reguliert Zahlungsdienste im EU-Binnenmarkt. Fuehrt Open Banking ein, verpflichtet zu starker Kundenauthentifizierung (SCA) und ermoeglicht Drittanbieterzugang zu Bankkonten.',
    relevantFor: ['Banken', 'Zahlungsdienstleister', 'FinTechs', 'E-Commerce-Anbieter', 'Kontoinformationsdienste'],
    keyTopics: ['Strong Customer Authentication (SCA)', 'Open Banking APIs', 'PSD2-Schnittstellen', 'Kontoinformationsdienste', 'Zahlungsauslösedienste'],
    effectiveDate: '13. Januar 2018'
  },
  {
    code: 'AMLR',
    name: 'AML-Verordnung',
    fullName: 'Verordnung (EU) 2024/1624 - Anti-Money Laundering Regulation',
    type: 'eu_regulation',
    expected: 89,
    description: 'EU-weite Verordnung zur Bekaempfung von Geldwaesche und Terrorismusfinanzierung. Ersetzt die bisherigen Richtlinien durch direkt anwendbare Vorschriften. Schafft einheitliche Sorgfaltspflichten.',
    relevantFor: ['Banken', 'Finanzdienstleister', 'Krypto-Anbieter', 'Immobilienmakler', 'Wirtschaftspruefer', 'Notare'],
    keyTopics: ['Sorgfaltspflichten (KYC)', 'Verdachtsmeldungen', 'Wirtschaftlich Berechtigte', 'Risikobewertung', 'AMLA (neue EU-Behoerde)'],
    effectiveDate: '2027 (gestaffelt)'
  },
  {
    code: 'MiCA',
    name: 'MiCA',
    fullName: 'Verordnung (EU) 2023/1114 - Markets in Crypto-Assets',
    type: 'eu_regulation',
    expected: 149,
    description: 'Umfassende Regulierung fuer Kryptowerte, Stablecoins und Crypto-Asset-Dienstleister. Schafft EU-weiten Rechtsrahmen fuer Krypto-Maerkte mit Zulassungspflichten und Verbraucherschutz.',
    relevantFor: ['Krypto-Boersen', 'Wallet-Anbieter', 'Stablecoin-Emittenten', 'Token-Herausgeber', 'Krypto-Verwahrer', 'FinTechs'],
    keyTopics: ['Krypto-Zulassung', 'Stablecoin-Regulierung', 'Whitepaper-Pflicht', 'Marktmissbrauch', 'Verwahrung'],
    effectiveDate: '30. Dezember 2024'
  },
  {
    code: 'EHDS',
    name: 'EHDS',
    fullName: 'Verordnung (EU) 2025/327 - Europaeischer Gesundheitsdatenraum',
    type: 'eu_regulation',
    expected: 95,
    description: 'Schafft den Europaeischen Raum fuer Gesundheitsdaten. Ermoeglicht Primaernutzung (Patientenrechte) und Sekundaernutzung (Forschung, KI-Training) von Gesundheitsdaten unter strengen Auflagen.',
    relevantFor: ['Krankenhaeuser', 'Aerzte', 'Gesundheits-Apps', 'Pharma', 'Forschungseinrichtungen', 'Versicherungen'],
    keyTopics: ['Patientenakte (MyHealth@EU)', 'Sekundaernutzung', 'Datenzugangsorgane', 'Gesundheitsdatenstandards', 'Forschungszugang'],
    effectiveDate: '2025 (gestaffelt bis 2029)'
  },
  // National Data Protection Laws (migrated from bp_dsfa_corpus)
  {
    code: 'AT_DSG',
    name: 'DSG Oesterreich',
    fullName: 'Datenschutzgesetz Oesterreich (DSG)',
    type: 'national_law',
    expected: 50,
    description: 'Oesterreichisches Datenschutzgesetz zur Ergaenzung der DSGVO. Regelt nationale Besonderheiten wie Bildverarbeitung, Datenschutzbehoerde und Strafbestimmungen.',
    relevantFor: ['Unternehmen in Oesterreich', 'DACH-Unternehmen', 'Auftragsverarbeiter'],
    keyTopics: ['Nationale DSGVO-Ergaenzung', 'Bildverarbeitung', 'Datenschutzbehoerde', 'Strafbestimmungen'],
    effectiveDate: '25. Mai 2018'
  },
  {
    code: 'BDSG_FULL',
    name: 'BDSG',
    fullName: 'Bundesdatenschutzgesetz (BDSG) - Volltext',
    type: 'de_law',
    expected: 9,
    description: 'Deutsches Bundesdatenschutzgesetz als nationale Ergaenzung zur DSGVO. Regelt Beschaeftigtendatenschutz, Videoueberachung, Scoring und Datenschutzbeauftragte.',
    relevantFor: ['Deutsche Unternehmen', 'Arbeitgeber', 'Auskunfteien', 'Oeffentliche Stellen'],
    keyTopics: ['Beschaeftigtendatenschutz', 'Videoueberachung', 'Scoring', 'Datenschutzbeauftragter'],
    effectiveDate: '25. Mai 2018'
  },
  {
    code: 'CH_DSG',
    name: 'DSG Schweiz',
    fullName: 'Datenschutzgesetz Schweiz (revDSG 2023)',
    type: 'national_law',
    expected: 2,
    description: 'Revidiertes Schweizer Datenschutzgesetz mit DSGVO-nahen Anforderungen. Gilt fuer Schweizer Unternehmen und solche, die Schweizer Daten verarbeiten.',
    relevantFor: ['Schweizer Unternehmen', 'DACH-Unternehmen', 'Internationale Dienstleister'],
    keyTopics: ['Datenschutz-Folgenabschaetzung', 'Meldepflichten', 'Profiling', 'Strafbestimmungen'],
    effectiveDate: '1. September 2023'
  },
  {
    code: 'LI_DSG',
    name: 'DSG Liechtenstein',
    fullName: 'Datenschutzgesetz Liechtenstein',
    type: 'national_law',
    expected: 1,
    description: 'Liechtensteinisches Datenschutzgesetz als EWR-Umsetzung der DSGVO.',
    relevantFor: ['Unternehmen in Liechtenstein', 'EWR-Dienstleister'],
    keyTopics: ['EWR-Datenschutz', 'Nationale Ergaenzung', 'Datenschutzstelle'],
    effectiveDate: '2018'
  },
  {
    code: 'BE_DPA_LAW',
    name: 'Datenschutzgesetz Belgien',
    fullName: 'Loi relative a la protection des donnees (Belgien)',
    type: 'national_law',
    expected: 153,
    description: 'Belgisches Datenschutzgesetz zur nationalen Umsetzung der DSGVO. Regelt die Autorite de protection des donnees (APD).',
    relevantFor: ['Unternehmen in Belgien', 'EU-Hauptsitz Bruessel'],
    keyTopics: ['APD', 'Nationale DSGVO-Umsetzung', 'Strafbestimmungen', 'Sektorale Regeln'],
    effectiveDate: '2018'
  },
  {
    code: 'NL_UAVG',
    name: 'UAVG Niederlande',
    fullName: 'Uitvoeringswet AVG (UAVG) Niederlande',
    type: 'national_law',
    expected: 138,
    description: 'Niederlaendisches Ausfuehrungsgesetz zur DSGVO. Regelt nationale Besonderheiten wie BSN-Verarbeitung und Gesundheitsdaten.',
    relevantFor: ['Unternehmen in den Niederlanden', 'Gesundheitssektor NL'],
    keyTopics: ['BSN-Nummer', 'Gesundheitsdaten', 'Autoriteit Persoonsgegevens', 'Nationale Ergaenzung'],
    effectiveDate: '25. Mai 2018'
  },
  {
    code: 'FR_CNIL_GUIDE',
    name: 'CNIL Guide RGPD',
    fullName: 'Guide pratique RGPD (CNIL Frankreich)',
    type: 'national_law',
    expected: 14,
    description: 'Praktischer DSGVO-Leitfaden der franzoesischen Datenschutzbehoerde CNIL. Wichtig fuer alle Unternehmen mit franzoesischen Kunden.',
    relevantFor: ['Unternehmen in Frankreich', 'Franzoesischsprachige Maerkte'],
    keyTopics: ['CNIL-Guidance', 'Cookies', 'Einwilligung', 'Sanktionen'],
    effectiveDate: '2018'
  },
  {
    code: 'ES_LOPDGDD',
    name: 'LOPDGDD Spanien',
    fullName: 'Ley Organica de Proteccion de Datos (LOPDGDD) Spanien',
    type: 'national_law',
    expected: 154,
    description: 'Spanisches organisches Datenschutzgesetz mit Garantien digitaler Rechte. Umfassende DSGVO-Umsetzung mit digitalen Grundrechten.',
    relevantFor: ['Unternehmen in Spanien', 'Spanischsprachige Maerkte'],
    keyTopics: ['Digitale Rechte', 'AEPD', 'Recht auf Vergessenwerden', 'Beschaeftigtendatenschutz'],
    effectiveDate: '7. Dezember 2018'
  },
  {
    code: 'IT_CODICE_PRIVACY',
    name: 'Codice Privacy Italien',
    fullName: 'Codice in materia di protezione dei dati personali (Italien)',
    type: 'national_law',
    expected: 3,
    description: 'Italienisches Datenschutzgesetzbuch, aktualisiert gemaess DSGVO. Umfassende nationale Regelung durch den Garante.',
    relevantFor: ['Unternehmen in Italien', 'Garante-regulierte Sektoren'],
    keyTopics: ['Garante Privacy', 'Codice Privacy', 'Gesundheitsdaten', 'Strafrecht'],
    effectiveDate: '2018 (aktualisiert)'
  },
  {
    code: 'IE_DPA_2018',
    name: 'DPA 2018 Ireland',
    fullName: 'Data Protection Act 2018 (Ireland)',
    type: 'national_law',
    expected: 28,
    description: 'Irisches Datenschutzgesetz. Besonders relevant da viele Tech-Konzerne (Google, Meta, Apple) ihren EU-Hauptsitz in Irland haben.',
    relevantFor: ['Tech-Konzerne mit EU-Sitz Irland', 'Irische Unternehmen', 'DPC-reguliert'],
    keyTopics: ['DPC Ireland', 'Big Tech Aufsicht', 'Nationale Ergaenzung', 'Strafbestimmungen'],
    effectiveDate: '24. Mai 2018'
  },
  {
    code: 'UK_DPA_2018',
    name: 'DPA 2018 UK',
    fullName: 'Data Protection Act 2018 (United Kingdom)',
    type: 'national_law',
    expected: 94,
    description: 'Britisches Datenschutzgesetz nach dem Brexit. Ergaenzt die UK GDPR mit nationalen Bestimmungen, reguliert durch das ICO.',
    relevantFor: ['Unternehmen mit UK-Kunden', 'UK-Datentransfers', 'ICO-regulierte Unternehmen'],
    keyTopics: ['ICO', 'UK Adequacy', 'Post-Brexit Datenschutz', 'Law Enforcement'],
    effectiveDate: '23. Mai 2018'
  },
  {
    code: 'UK_GDPR',
    name: 'UK GDPR',
    fullName: 'UK General Data Protection Regulation (retained EU law)',
    type: 'national_law',
    expected: 24,
    description: 'In UK-Recht ueberfuehrte DSGVO nach dem Brexit. Weitgehend identisch mit EU-DSGVO, aber unter britischer Aufsicht (ICO).',
    relevantFor: ['UK-Unternehmen', 'EU-UK Datentransfers', 'Internationale Konzerne'],
    keyTopics: ['Retained EU Law', 'UK-EU Adequacy', 'ICO Enforcement', 'UK-spezifische Anpassungen'],
    effectiveDate: '1. Januar 2021'
  },
  {
    code: 'NO_PERSONOPPLYSNINGSLOVEN',
    name: 'Personopplysningsloven',
    fullName: 'Personopplysningsloven (Norwegen)',
    type: 'national_law',
    expected: 18,
    description: 'Norwegisches Datenschutzgesetz als EWR-Umsetzung der DSGVO. Reguliert durch Datatilsynet.',
    relevantFor: ['Unternehmen in Norwegen', 'EWR-Dienstleister', 'Skandinavische Maerkte'],
    keyTopics: ['Datatilsynet', 'EWR-Datenschutz', 'Nationale Ergaenzung', 'Kameras'],
    effectiveDate: '20. Juli 2018'
  },
  {
    code: 'SE_DATASKYDDSLAG',
    name: 'Dataskyddslag Schweden',
    fullName: 'Dataskyddslag (2018:218) Schweden',
    type: 'national_law',
    expected: 30,
    description: 'Schwedisches Datenschutzgesetz als ergaenzende Bestimmungen zur DSGVO. Reguliert durch IMY.',
    relevantFor: ['Unternehmen in Schweden', 'Skandinavische Maerkte'],
    keyTopics: ['IMY', 'Personnummer', 'Forschungsdaten', 'Pressefreiheit'],
    effectiveDate: '25. Mai 2018'
  },
  {
    code: 'FI_TIETOSUOJALAKI',
    name: 'Tietosuojalaki Finnland',
    fullName: 'Tietosuojalaki (1050/2018) Finnland',
    type: 'national_law',
    expected: 1,
    description: 'Finnisches Datenschutzgesetz als nationale Ergaenzung zur DSGVO.',
    relevantFor: ['Unternehmen in Finnland', 'Nordische Maerkte'],
    keyTopics: ['Nationale Ergaenzung', 'Tietosuojavaltuutettu', 'Forschungsdaten'],
    effectiveDate: '1. Januar 2019'
  },
  {
    code: 'PL_UODO',
    name: 'UODO Polen',
    fullName: 'Ustawa o ochronie danych osobowych (Polen)',
    type: 'national_law',
    expected: 1,
    description: 'Polnisches Datenschutzgesetz als DSGVO-Umsetzung. Reguliert durch den UODO (Praesident des Amtes fuer den Schutz personenbezogener Daten).',
    relevantFor: ['Unternehmen in Polen', 'Osteuropaeische Maerkte'],
    keyTopics: ['UODO', 'Nationale Ergaenzung', 'Strafbestimmungen', 'Oeffentlicher Sektor'],
    effectiveDate: '25. Mai 2018'
  },
  {
    code: 'CZ_ZOU',
    name: 'Zakon Tschechien',
    fullName: 'Zakon o zpracovani osobnich udaju (Tschechien)',
    type: 'national_law',
    expected: 135,
    description: 'Tschechisches Datenschutzgesetz zur DSGVO-Umsetzung. Reguliert durch das UOOU.',
    relevantFor: ['Unternehmen in Tschechien', 'Mitteleuropaeische Maerkte'],
    keyTopics: ['UOOU', 'Nationale Ergaenzung', 'Kamerasysteme', 'Strafbestimmungen'],
    effectiveDate: '24. April 2019'
  },
  {
    code: 'HU_INFOTV',
    name: 'Infotv. Ungarn',
    fullName: 'Informacios torvenye (Infotv.) Ungarn',
    type: 'national_law',
    expected: 156,
    description: 'Ungarisches Informationsgesetz ueber Selbstbestimmung und Informationsfreiheit als DSGVO-Ergaenzung. Reguliert durch NAIH.',
    relevantFor: ['Unternehmen in Ungarn', 'Mitteleuropaeische Maerkte'],
    keyTopics: ['NAIH', 'Informationsfreiheit', 'Nationale Ergaenzung', 'Datensicherheit'],
    effectiveDate: '2018 (aktualisiert)'
  },
  {
    code: 'SCC_FULL_TEXT',
    name: 'SCC Volltext',
    fullName: 'Standardvertragsklauseln Volltext (2021/914/EU)',
    type: 'eu_regulation',
    expected: 154,
    description: 'Vollstaendiger Text der EU-Standardvertragsklauseln fuer internationale Datentransfers. Alle Module (C2C, C2P, P2C, P2P) mit Annexen.',
    relevantFor: ['Alle mit Drittlandtransfers', 'Cloud-Nutzer', 'Auftragsverarbeiter'],
    keyTopics: ['Module 1-4', 'TIA', 'Annexe', 'Technische Massnahmen'],
    effectiveDate: '27. Juni 2021'
  },
  {
    code: 'EDPB_GUIDELINES_2_2019',
    name: 'EDPB GL Art. 6(1)(b)',
    fullName: 'EDPB Leitlinien 2/2019 zu Art. 6(1)(b) DSGVO',
    type: 'eu_guideline',
    expected: 3,
    description: 'EDPB-Leitlinien zur Verarbeitung personenbezogener Daten auf Grundlage der Vertragserfullung gemaess Art. 6 Abs. 1 lit. b DSGVO.',
    relevantFor: ['Alle Verantwortlichen', 'Vertragsdatenverarbeitung', 'Online-Dienste'],
    keyTopics: ['Vertragserfullung', 'Art. 6(1)(b)', 'Erforderlichkeit', 'Online-Dienste'],
    effectiveDate: '2019'
  },
  {
    code: 'EDPB_GUIDELINES_3_2019',
    name: 'EDPB GL Videoueberwachung',
    fullName: 'EDPB Leitlinien 3/2019 Videoueberwachung',
    type: 'eu_guideline',
    expected: 3,
    description: 'EDPB-Leitlinien zur Verarbeitung personenbezogener Daten durch Videoueberwachungsgeraete.',
    relevantFor: ['Videoueberwachung', 'Sicherheitsdienste', 'Einzelhandel', 'Oeffentliche Stellen'],
    keyTopics: ['Videoueberwachung', 'Kameras', 'Speicherfristen', 'Hinweisschilder'],
    effectiveDate: '2020'
  },
  {
    code: 'EDPB_GUIDELINES_5_2020',
    name: 'EDPB GL Einwilligung',
    fullName: 'EDPB Leitlinien 5/2020 zur Einwilligung',
    type: 'eu_guideline',
    expected: 2,
    description: 'EDPB-Leitlinien zur Einwilligung gemaess DSGVO. Klaert Anforderungen an gueltige Einwilligungen, Widerruf und Cookie-Consent.',
    relevantFor: ['Website-Betreiber', 'Marketing', 'App-Entwickler', 'Consent-Management'],
    keyTopics: ['Einwilligung', 'Cookie-Consent', 'Widerruf', 'Freiwilligkeit'],
    effectiveDate: '2020'
  },
  {
    code: 'EDPB_GUIDELINES_7_2020',
    name: 'EDPB GL Controller/Processor',
    fullName: 'EDPB Leitlinien 7/2020 Controller und Processor',
    type: 'eu_guideline',
    expected: 2,
    description: 'EDPB-Leitlinien zu den Begriffen Verantwortlicher und Auftragsverarbeiter. Klaert Rollen, Pflichten und Joint Controllership.',
    relevantFor: ['Alle Verantwortlichen', 'Auftragsverarbeiter', 'Joint Controller'],
    keyTopics: ['Verantwortlicher', 'Auftragsverarbeiter', 'Joint Controller', 'AVV'],
    effectiveDate: '2021'
  },
  // =====================================================================
  // DACH National Laws — Deutschland
  // =====================================================================
  {
    code: 'DE_DDG',
    name: 'Digitale-Dienste-Gesetz',
    fullName: 'Digitale-Dienste-Gesetz (DDG)',
    type: 'de_law',
    expected: 30,
    description: 'Deutsches Umsetzungsgesetz zum DSA. Regelt Impressumspflicht (§5 DDG), Informationspflichten fuer digitale Dienste und Cookie-Consent.',
    relevantFor: ['Website-Betreiber', 'Online-Dienste', 'Plattformen'],
    keyTopics: ['Impressumspflicht §5', 'Informationspflichten', 'Digitale Dienste'],
    effectiveDate: '14. Mai 2024'
  },
  {
    code: 'DE_BGB_AGB',
    name: 'BGB AGB-Recht',
    fullName: 'BGB §§305-310, 312-312k — AGB und Fernabsatz',
    type: 'de_law',
    expected: 40,
    description: 'Deutsches AGB-Recht: Einbeziehungskontrolle (§305), Inhaltskontrolle (§307), Klauselverbote (§§308-309). Fernabsatz: Widerrufsrecht, Button-Loesung.',
    relevantFor: ['Alle Unternehmen mit AGB', 'Online-Shops', 'SaaS-Anbieter', 'Dienstleister'],
    keyTopics: ['AGB-Kontrolle', 'Klauselverbote', 'Widerrufsrecht', 'Button-Loesung', 'Fernabsatz'],
    effectiveDate: 'Dauerhaft gueltig'
  },
  {
    code: 'DE_EGBGB',
    name: 'EGBGB Art. 246-248',
    fullName: 'EGBGB — Informationspflichten bei Verbrauchervertraegen',
    type: 'de_law',
    expected: 20,
    description: 'Detaillierte Informationspflichten bei Verbrauchervertraegen (Art. 246), Fernabsatz (Art. 246a) und E-Commerce (Art. 246c).',
    relevantFor: ['Online-Shops', 'E-Commerce', 'Dienstleister', 'App-Anbieter'],
    keyTopics: ['Vorvertragliche Information', 'Widerrufsbelehrung', 'E-Commerce-Pflichten'],
    effectiveDate: 'Dauerhaft gueltig'
  },
  {
    code: 'DE_UWG',
    name: 'UWG Deutschland',
    fullName: 'Gesetz gegen den unlauteren Wettbewerb (UWG)',
    type: 'de_law',
    expected: 25,
    description: 'Schutz vor unlauterem Wettbewerb: irrefuehrende Werbung, Spam-Verbot, Preisangaben, Online-Marketing-Regeln.',
    relevantFor: ['Marketing', 'Vertrieb', 'Online-Shops', 'Werbetreibende'],
    keyTopics: ['Irrefuehrende Werbung', 'Spam-Verbot', 'Dark Patterns', 'Preisangaben'],
    effectiveDate: '2004 (laufend aktualisiert)'
  },
  {
    code: 'DE_HGB_RET',
    name: 'HGB Aufbewahrung',
    fullName: 'HGB §§238-261, 257 — Handelsbuecher und Aufbewahrungsfristen',
    type: 'de_law',
    expected: 15,
    description: 'Buchfuehrungspflicht und handelsrechtliche Aufbewahrungsfristen: 6 Jahre (Handelsbriefe) und 10 Jahre (Buchungsbelege, Jahresabschluesse).',
    relevantFor: ['Alle Kaufleute', 'Kapitalgesellschaften', 'Buchhaltung'],
    keyTopics: ['Aufbewahrung 6/10 Jahre', 'Buchfuehrungspflicht', 'Elektronische Aufbewahrung'],
    effectiveDate: 'Dauerhaft gueltig'
  },
  {
    code: 'DE_AO_RET',
    name: 'AO Aufbewahrung',
    fullName: 'Abgabenordnung §§140-148 — Steuerliche Aufbewahrungspflichten',
    type: 'de_law',
    expected: 12,
    description: 'Steuerliche Buchfuehrungs- und Aufbewahrungspflichten. 6/10 Jahre Fristen, Datenzugriff durch Finanzbehoerden (§147 Abs. 6).',
    relevantFor: ['Alle Steuerpflichtigen', 'Gewerbetreibende', 'Buchhaltung'],
    keyTopics: ['Steuerliche Aufbewahrung', 'Datenzugriff Finanzamt', 'GoBD'],
    effectiveDate: 'Dauerhaft gueltig'
  },
  {
    code: 'DE_TKG',
    name: 'TKG 2021',
    fullName: 'Telekommunikationsgesetz 2021',
    type: 'de_law',
    expected: 45,
    description: 'Telekommunikationsregulierung: Kundenschutz, Datenschutz, Vertragslaufzeiten max. 24 Monate, Netzinfrastruktur.',
    relevantFor: ['Telekommunikationsanbieter', 'VoIP-Dienste', 'ISPs'],
    keyTopics: ['Kundenschutz', 'Vertragslaufzeiten', 'Fernmeldegeheimnis', 'Netzneutralitaet'],
    effectiveDate: '1. Dezember 2021'
  },
  {
    code: 'DE_PANGV',
    name: 'PAngV',
    fullName: 'Preisangabenverordnung (PAngV 2022)',
    type: 'de_law',
    expected: 15,
    description: 'Preisangaben: Gesamtpreis, Grundpreis, Streichpreise (§11 — 30-Tage-Regel), Online-Preisauszeichnung.',
    relevantFor: ['Online-Shops', 'Einzelhandel', 'Marktplaetze'],
    keyTopics: ['Gesamtpreis', 'Grundpreis', 'Streichpreis-Regel', 'Online-Preise'],
    effectiveDate: '28. Mai 2022'
  },
  {
    code: 'DE_DLINFOV',
    name: 'DL-InfoV',
    fullName: 'Dienstleistungs-Informationspflichten-Verordnung',
    type: 'de_law',
    expected: 10,
    description: 'Informationspflichten fuer Dienstleister: Identitaet, Kontakt, Berufshaftpflicht, AGB-Zugang.',
    relevantFor: ['Dienstleister', 'Freiberufler', 'Handwerker'],
    keyTopics: ['Dienstleister-Impressum', 'Kontaktdaten', 'Berufshaftpflicht'],
    effectiveDate: '17. Mai 2010'
  },
  {
    code: 'DE_BETRVG',
    name: 'BetrVG §87',
    fullName: 'Betriebsverfassungsgesetz §87 Abs.1 Nr.6',
    type: 'de_law',
    expected: 5,
    description: 'Mitbestimmung des Betriebsrats bei technischer Ueberwachung: IT-Systeme die Arbeitnehmerverhalten ueberwachen koennen.',
    relevantFor: ['Arbeitgeber mit Betriebsrat', 'IT-Abteilungen', 'HR'],
    keyTopics: ['Mitbestimmung', 'Technische Ueberwachung', 'IT-Systeme', 'DSFA-Pflicht'],
    effectiveDate: '1972 (laufend aktualisiert)'
  },
  {
    code: 'DE_GESCHGEHG',
    name: 'GeschGehG',
    fullName: 'Gesetz zum Schutz von Geschaeftsgeheimnissen',
    type: 'de_law',
    expected: 10,
    description: 'Schutz von Geschaeftsgeheimnissen: Definition, angemessene Geheimhaltungsmassnahmen erforderlich, Reverse Engineering erlaubt.',
    relevantFor: ['Alle Unternehmen', 'IT-Sicherheit', 'F&E-Abteilungen'],
    keyTopics: ['Geschaeftsgeheimnis-Definition', 'Geheimhaltungsmassnahmen', 'Reverse Engineering'],
    effectiveDate: '26. April 2019'
  },
  {
    code: 'DE_BSIG',
    name: 'BSI-Gesetz',
    fullName: 'Gesetz ueber das Bundesamt fuer Sicherheit in der Informationstechnik',
    type: 'de_law',
    expected: 20,
    description: 'BSI-Aufgaben, KRITIS-Meldepflichten, IT-Sicherheitsstandards, Zertifizierung, Warn- und Empfehlungsbefugnis.',
    relevantFor: ['KRITIS-Betreiber', 'IT-Sicherheit', 'Cloud-Anbieter'],
    keyTopics: ['KRITIS-Meldepflicht', 'IT-Sicherheitsstandards', 'BSI-Zertifizierung'],
    effectiveDate: '2009 (laufend aktualisiert)'
  },
  {
    code: 'DE_USTG_RET',
    name: 'UStG §14b',
    fullName: 'Umsatzsteuergesetz §14b — Aufbewahrung von Rechnungen',
    type: 'de_law',
    expected: 5,
    description: 'Aufbewahrungspflicht fuer Rechnungen: 10 Jahre, Grundstuecke 20 Jahre, elektronische Aufbewahrung.',
    relevantFor: ['Alle Unternehmer', 'Buchhaltung', 'Steuerberater'],
    keyTopics: ['Rechnungsaufbewahrung', '10/20 Jahre Frist', 'Elektronische Rechnungen'],
    effectiveDate: 'Dauerhaft gueltig'
  },
  // =====================================================================
  // DACH National Laws — Oesterreich
  // =====================================================================
  {
    code: 'AT_ECG',
    name: 'E-Commerce-Gesetz AT',
    fullName: 'E-Commerce-Gesetz (ECG) Oesterreich',
    type: 'at_law',
    expected: 30,
    description: 'Oesterreichisches E-Commerce-Gesetz: Impressum/Offenlegungspflicht (§5), Informationspflichten, Haftung von Diensteanbietern.',
    relevantFor: ['Oesterreichische Online-Dienste', 'E-Commerce AT', 'Website-Betreiber'],
    keyTopics: ['Impressum §5 ECG', 'Offenlegungspflicht', 'Diensteanbieter-Haftung'],
    effectiveDate: '1. Januar 2002'
  },
  {
    code: 'AT_TKG',
    name: 'TKG 2021 AT',
    fullName: 'Telekommunikationsgesetz 2021 Oesterreich',
    type: 'at_law',
    expected: 40,
    description: 'Oesterreichisches TKG: Cookie-Bestimmungen (§165), Kommunikationsgeheimnis, Endgeraetezugriff, Spam-Verbot.',
    relevantFor: ['Oesterreichische Websites', 'Telekommunikation AT', 'App-Anbieter'],
    keyTopics: ['Cookies §165', 'Kommunikationsgeheimnis', 'Endgeraetezugriff', 'Spam-Verbot'],
    effectiveDate: '1. November 2021'
  },
  {
    code: 'AT_KSCHG',
    name: 'KSchG Oesterreich',
    fullName: 'Konsumentenschutzgesetz (KSchG) Oesterreich',
    type: 'at_law',
    expected: 35,
    description: 'Konsumentenschutz: AGB-Kontrolle (§6 Klauselverbote, §9 Verbandsklage), Ruecktrittsrecht bei Haustuergeschaeften.',
    relevantFor: ['Unternehmen mit oesterreichischen Verbrauchern', 'E-Commerce AT'],
    keyTopics: ['AGB-Klauselverbote §6', 'Verbandsklage §9', 'Ruecktrittsrecht', 'Transparenzkontrolle'],
    effectiveDate: '1. Oktober 1979 (laufend aktualisiert)'
  },
  {
    code: 'AT_FAGG',
    name: 'FAGG Oesterreich',
    fullName: 'Fern- und Auswaertsgeschaefte-Gesetz (FAGG) Oesterreich',
    type: 'at_law',
    expected: 20,
    description: 'Fernabsatzrecht: Informationspflichten, Widerrufsrecht 14 Tage, Button-Loesung, Ausnahmen.',
    relevantFor: ['Oesterreichische Online-Shops', 'Fernabsatz AT', 'Versandhandel'],
    keyTopics: ['Widerrufsrecht 14 Tage', 'Informationspflichten', 'Button-Loesung', 'Kostenfolgen'],
    effectiveDate: '13. Juni 2014'
  },
  {
    code: 'AT_UGB_RET',
    name: 'UGB Aufbewahrung AT',
    fullName: 'UGB §§189-216, 212 — Rechnungslegung und Aufbewahrung Oesterreich',
    type: 'at_law',
    expected: 15,
    description: 'Oesterreichische Rechnungslegungspflicht und Aufbewahrungsfristen (7 Jahre). Buchfuehrung, Jahresabschluss.',
    relevantFor: ['Oesterreichische Kapitalgesellschaften', 'Unternehmen >700k EUR Umsatz'],
    keyTopics: ['Aufbewahrung 7 Jahre', 'Rechnungslegung', 'Buchfuehrung'],
    effectiveDate: 'Dauerhaft gueltig'
  },
  {
    code: 'AT_BAO_RET',
    name: 'BAO §132 AT',
    fullName: 'Bundesabgabenordnung §132 — Aufbewahrung Oesterreich',
    type: 'at_law',
    expected: 5,
    description: 'Steuerliche Aufbewahrungspflicht 7 Jahre fuer Buecher, Aufzeichnungen und Belege. Grundstuecke 22 Jahre.',
    relevantFor: ['Oesterreichische Steuerpflichtige', 'Buchhaltung AT'],
    keyTopics: ['Aufbewahrung 7 Jahre', 'Grundstuecke 22 Jahre', 'Steuerliche Belege'],
    effectiveDate: 'Dauerhaft gueltig'
  },
  {
    code: 'AT_MEDIENG',
    name: 'MedienG §§24-25 AT',
    fullName: 'Mediengesetz §§24-25 Oesterreich — Impressum und Offenlegung',
    type: 'at_law',
    expected: 10,
    description: 'Impressum/Offenlegungspflicht fuer periodische Medien und Websites in Oesterreich.',
    relevantFor: ['Medienunternehmen AT', 'Website-Betreiber AT', 'Blogger AT'],
    keyTopics: ['Impressum', 'Offenlegung', 'Medieninhaber', 'Periodische Medien'],
    effectiveDate: '1. Januar 1982 (laufend aktualisiert)'
  },
  {
    code: 'AT_ABGB_AGB',
    name: 'ABGB AGB-Recht AT',
    fullName: 'ABGB §§861-879, 864a — AGB-Kontrolle Oesterreich',
    type: 'at_law',
    expected: 10,
    description: 'Geltungskontrolle (§864a — ueberraschende Klauseln), Sittenwidrigkeitskontrolle (§879 Abs.3 — groebliche Benachteiligung).',
    relevantFor: ['Unternehmen mit oesterreichischen Kunden', 'AGB-Ersteller'],
    keyTopics: ['Geltungskontrolle §864a', 'Inhaltskontrolle §879', 'Groebliche Benachteiligung'],
    effectiveDate: '1. Juni 1811 (laufend aktualisiert)'
  },
  {
    code: 'AT_UWG',
    name: 'UWG Oesterreich',
    fullName: 'Bundesgesetz gegen den unlauteren Wettbewerb Oesterreich',
    type: 'at_law',
    expected: 15,
    description: 'Lauterkeitsrecht AT: irrefuehrende Geschaeftspraktiken, aggressive Praktiken, Preisauszeichnung.',
    relevantFor: ['Marketing AT', 'Vertrieb AT', 'Werbetreibende AT'],
    keyTopics: ['Irrefuehrung', 'Aggressive Praktiken', 'Preisauszeichnung', 'Unterlassungsklagen'],
    effectiveDate: '1984 (laufend aktualisiert)'
  },
  // =====================================================================
  // DACH National Laws — Schweiz
  // =====================================================================
  {
    code: 'CH_DSV',
    name: 'DSV Schweiz',
    fullName: 'Datenschutzverordnung (DSV) Schweiz — SR 235.11',
    type: 'ch_law',
    expected: 30,
    description: 'Ausfuehrungsverordnung zum revDSG: Meldepflichten, DSFA-Verfahren, Auslandtransfers, technische Massnahmen.',
    relevantFor: ['Schweizer Unternehmen', 'DACH-Unternehmen', 'Datenexporteure CH'],
    keyTopics: ['Meldepflicht', 'DSFA-Verfahren', 'Datentransfer', 'Technische Massnahmen'],
    effectiveDate: '1. September 2023'
  },
  {
    code: 'CH_OR_AGB',
    name: 'OR AGB/Aufbewahrung CH',
    fullName: 'Obligationenrecht — AGB-Kontrolle und Aufbewahrung Schweiz (SR 220)',
    type: 'ch_law',
    expected: 20,
    description: 'Art. 8 OR (AGB-Inhaltskontrolle), Art. 19/20 (Vertragsfreiheit), Art. 957-958f (Buchfuehrung, 10 Jahre Aufbewahrung).',
    relevantFor: ['Schweizer Unternehmen', 'AGB-Ersteller CH', 'Buchhaltung CH'],
    keyTopics: ['AGB-Kontrolle Art. 8', 'Aufbewahrung 10 Jahre', 'Buchfuehrungspflicht'],
    effectiveDate: '1. Januar 2023 (AGB-Revision)'
  },
  {
    code: 'CH_UWG',
    name: 'UWG Schweiz',
    fullName: 'Bundesgesetz gegen den unlauteren Wettbewerb Schweiz (SR 241)',
    type: 'ch_law',
    expected: 20,
    description: 'Lauterkeitsrecht: Impressumspflicht, irrefuehrende Werbung, aggressive Verkaufsmethoden, AGB-Transparenz.',
    relevantFor: ['Schweizer Unternehmen', 'Marketing CH', 'Online-Shops CH'],
    keyTopics: ['Impressumspflicht', 'Irrefuehrende Werbung', 'AGB-Transparenz'],
    effectiveDate: '1. Maerz 1988 (laufend aktualisiert)'
  },
  {
    code: 'CH_FMG',
    name: 'FMG Schweiz',
    fullName: 'Fernmeldegesetz Schweiz (SR 784.10)',
    type: 'ch_law',
    expected: 25,
    description: 'Telekommunikationsregulierung: Fernmeldegeheimnis, Cookies/Tracking (Art. 45c), Spam-Verbot, Datenschutz.',
    relevantFor: ['Schweizer Websites', 'Telekommunikation CH', 'App-Anbieter CH'],
    keyTopics: ['Cookies Art. 45c', 'Fernmeldegeheimnis', 'Spam-Verbot', 'Tracking'],
    effectiveDate: '1. April 2007 (laufend aktualisiert)'
  },
  {
    code: 'CH_GEBUV',
    name: 'GeBuV Schweiz',
    fullName: 'Geschaeftsbuecher-Verordnung Schweiz (SR 221.431)',
    type: 'ch_law',
    expected: 10,
    description: 'Ausfuehrungsvorschriften zur Buchfuehrung: elektronische Aufbewahrung, Integritaet, Datentraeger.',
    relevantFor: ['Schweizer Unternehmen', 'Buchhaltung CH', 'IT-Archivierung'],
    keyTopics: ['Elektronische Aufbewahrung', 'Integritaet', 'Unveraenderbarkeit'],
    effectiveDate: '1. Juni 2002'
  },
  {
    code: 'CH_ZERTES',
    name: 'ZertES Schweiz',
    fullName: 'Bundesgesetz ueber die elektronische Signatur (SR 943.03)',
    type: 'ch_law',
    expected: 10,
    description: 'Elektronische Signatur und Zertifizierung: Qualifizierte Signaturen, Zertifizierungsdiensteanbieter.',
    relevantFor: ['Vertragsmanagement CH', 'AVV-Erstellung', 'E-Government CH'],
    keyTopics: ['Qualifizierte Signatur', 'Zertifizierungsdienste', 'Rechtswirkung'],
    effectiveDate: '1. Januar 2017'
  },
  {
    code: 'CH_ZGB_PERS',
    name: 'ZGB Persoenlichkeitsschutz CH',
    fullName: 'Zivilgesetzbuch Art. 28-28l — Persoenlichkeitsschutz Schweiz (SR 210)',
    type: 'ch_law',
    expected: 8,
    description: 'Persoenlichkeitsschutz: Recht am eigenen Bild, Schutz der Privatsphaere, Gegendarstellungsrecht.',
    relevantFor: ['Medien CH', 'Social Media', 'Datenschutz CH'],
    keyTopics: ['Persoenlichkeitsschutz', 'Recht am Bild', 'Gegendarstellung'],
    effectiveDate: '1. Juli 1985 (laufend aktualisiert)'
  },
  // =====================================================================
  // 3 fehlgeschlagene Quellen mit korrigierten URLs
  // =====================================================================
  {
    code: 'LU_DPA_LAW',
    name: 'Datenschutzgesetz Luxemburg',
    fullName: 'Loi du 1er aout 2018 — Datenschutzgesetz Luxemburg',
    type: 'national_law',
    expected: 40,
    description: 'Luxemburgisches Datenschutzgesetz: Organisation der CNPD, nationale DSGVO-Ergaenzung.',
    relevantFor: ['Unternehmen in Luxemburg', 'EU-Finanzplatz', 'CNPD-reguliert'],
    keyTopics: ['CNPD', 'Nationale DSGVO-Umsetzung', 'Strafbestimmungen'],
    effectiveDate: '1. August 2018'
  },
  {
    code: 'DK_DATABESKYTTELSESLOVEN',
    name: 'Databeskyttelsesloven DK',
    fullName: 'Databeskyttelsesloven — Datenschutzgesetz Daenemark',
    type: 'national_law',
    expected: 30,
    description: 'Daenisches Datenschutzgesetz als ergaenzende Bestimmungen zur DSGVO. Reguliert durch Datatilsynet.',
    relevantFor: ['Unternehmen in Daenemark', 'Skandinavische Maerkte'],
    keyTopics: ['Datatilsynet', 'Nationale DSGVO-Ergaenzung', 'Strafbestimmungen'],
    effectiveDate: '25. Mai 2018'
  },
  {
    code: 'EDPB_GUIDELINES_1_2022',
    name: 'EDPB GL Bussgelder',
    fullName: 'EDPB Leitlinien 04/2022 zur Berechnung von Bussgeldern nach der DSGVO',
    type: 'eu_guideline',
    expected: 15,
    description: 'EDPB-Leitlinien zur Berechnung von Verwaltungsbussgeldern unter der DSGVO. Systematik, Schwere, Milderungsgruende.',
    relevantFor: ['Datenschutzbeauftragte', 'Compliance-Abteilungen', 'Rechtsabteilungen'],
    keyTopics: ['Bussgeldberechnung', 'Schweregrad', 'Milderungsgruende', 'Bussgeldrahmen'],
    effectiveDate: '2022'
  },
  // =====================================================================
  // Neu ingestierte EU-Richtlinien (Februar 2026)
  // =====================================================================
  {
    code: 'E_COMMERCE_RL',
    name: 'E-Commerce-Richtlinie',
    fullName: 'Richtlinie 2000/31/EG ueber den elektronischen Geschaeftsverkehr',
    type: 'eu_directive',
    expected: 30,
    description: 'EU-Richtlinie ueber den elektronischen Geschaeftsverkehr (E-Commerce). Regelt Herkunftslandprinzip, Informationspflichten, Haftungsprivilegien fuer Vermittler (Mere Conduit, Caching, Hosting).',
    relevantFor: ['Online-Dienste', 'E-Commerce', 'Hosting-Anbieter', 'Plattformen'],
    keyTopics: ['Herkunftslandprinzip', 'Haftungsprivileg', 'Informationspflichten', 'Spam-Verbot', 'Vermittlerhaftung'],
    effectiveDate: '17. Juli 2000'
  },
  {
    code: 'VERBRAUCHERRECHTE_RL',
    name: 'Verbraucherrechte-Richtlinie',
    fullName: 'Richtlinie 2011/83/EU ueber die Rechte der Verbraucher',
    type: 'eu_directive',
    expected: 25,
    description: 'EU-weite Harmonisierung der Verbraucherrechte bei Fernabsatz und aussergeschaeftlichen Vertraegen. 14-Tage-Widerrufsrecht, Informationspflichten, digitale Inhalte.',
    relevantFor: ['Online-Shops', 'E-Commerce', 'Fernabsatz', 'Dienstleister'],
    keyTopics: ['Widerrufsrecht 14 Tage', 'Informationspflichten', 'Fernabsatzvertraege', 'Digitale Inhalte'],
    effectiveDate: '13. Juni 2014'
  },
  {
    code: 'DIGITALE_INHALTE_RL',
    name: 'Digitale-Inhalte-Richtlinie',
    fullName: 'Richtlinie (EU) 2019/770 ueber digitale Inhalte und Dienstleistungen',
    type: 'eu_directive',
    expected: 20,
    description: 'Gewaehrleistungsrecht fuer digitale Inhalte und Dienstleistungen. Regelt Maengelhaftung, Updates, Vertragsmaessigkeit und Kuendigungsrechte bei digitalen Produkten.',
    relevantFor: ['SaaS-Anbieter', 'App-Entwickler', 'Cloud-Dienste', 'Streaming-Anbieter', 'Software-Hersteller'],
    keyTopics: ['Digitale Gewaehrleistung', 'Update-Pflicht', 'Vertragsmaessigkeit', 'Kuendigungsrecht', 'Datenportabilitaet'],
    effectiveDate: '1. Januar 2022'
  },
  {
    code: 'DMA',
    name: 'Digital Markets Act',
    fullName: 'Verordnung (EU) 2022/1925 - Digital Markets Act',
    type: 'eu_regulation',
    expected: 50,
    description: 'Reguliert digitale Gatekeeper-Plattformen. Stellt Verhaltensregeln fuer grosse Plattformen auf (Apple, Google, Meta, Amazon, Microsoft). Verbietet Selbstbevorzugung und erzwingt Interoperabilitaet.',
    relevantFor: ['Grosse Plattformen', 'App-Stores', 'Suchmaschinen', 'Social Media', 'Messenger-Dienste'],
    keyTopics: ['Gatekeeper-Pflichten', 'Interoperabilitaet', 'Selbstbevorzugung', 'App-Store-Regeln', 'Datenportabilitaet'],
    effectiveDate: '2. Mai 2023'
  },
  // === Industrie-Compliance (2026-02-28) ===
  {
    code: 'MACHINERY_REG',
    name: 'Maschinenverordnung',
    fullName: 'Verordnung (EU) 2023/1230 ueber Maschinen (Machinery Regulation)',
    type: 'eu_regulation',
    expected: 100,
    description: 'Loest die alte Maschinenrichtlinie 2006/42/EG ab. Regelt Sicherheitsanforderungen fuer Maschinen und zugehoerige Produkte, CE-Kennzeichnung, Konformitaetsbewertung und Marktaufsicht. Neu: Cybersecurity-Anforderungen fuer vernetzte Maschinen.',
    relevantFor: ['Maschinenbau', 'Industrie 4.0', 'Automatisierung', 'Hersteller', 'Importeure'],
    keyTopics: ['CE-Kennzeichnung', 'Konformitaetsbewertung', 'Risikobeurteilung', 'Cybersecurity', 'Betriebsanleitung'],
    effectiveDate: '20. Januar 2027'
  },
  {
    code: 'BLUE_GUIDE',
    name: 'Blue Guide',
    fullName: 'Leitfaden fuer die Umsetzung der EU-Produktvorschriften (Blue Guide 2022)',
    type: 'eu_guideline',
    expected: 200,
    description: 'Umfassender Leitfaden der EU-Kommission zur Umsetzung von Produktvorschriften. Erklaert CE-Kennzeichnung, Konformitaetsbewertungsverfahren, notifizierte Stellen, Marktaufsicht und den New Legislative Framework.',
    relevantFor: ['Hersteller', 'Importeure', 'Haendler', 'Notifizierte Stellen', 'Marktaufsichtsbehoerden'],
    keyTopics: ['CE-Kennzeichnung', 'Konformitaetserklaerung', 'Notifizierte Stellen', 'Marktaufsicht', 'New Legislative Framework'],
    effectiveDate: '29. Juni 2022'
  },
  {
    code: 'ENISA_SECURE_BY_DESIGN',
    name: 'ENISA Secure by Design',
    fullName: 'ENISA Secure Software Development Best Practices',
    type: 'eu_guideline',
    expected: 50,
    description: 'ENISA-Leitfaden fuer sichere Softwareentwicklung. Beschreibt Best Practices fuer Security by Design, sichere Entwicklungsprozesse und Schwachstellenmanagement.',
    relevantFor: ['Softwareentwickler', 'DevOps', 'IT-Sicherheit', 'Produktmanagement'],
    keyTopics: ['Security by Design', 'SDLC', 'Schwachstellenmanagement', 'Secure Coding', 'Threat Modeling'],
    effectiveDate: '2023'
  },
  {
    code: 'ENISA_SUPPLY_CHAIN',
    name: 'ENISA Supply Chain Security',
    fullName: 'ENISA Threat Landscape for Supply Chain Attacks',
    type: 'eu_guideline',
    expected: 50,
    description: 'ENISA-Analyse der Bedrohungslandschaft fuer Supply-Chain-Angriffe. Beschreibt Angriffsvektoren, Taxonomie und Empfehlungen zur Absicherung von Software-Lieferketten.',
    relevantFor: ['IT-Sicherheit', 'Beschaffung', 'Softwareentwickler', 'CISO'],
    keyTopics: ['Supply Chain Security', 'SolarWinds', 'SBOM', 'Lieferantenrisiko', 'Third-Party Risk'],
    effectiveDate: '2021'
  },
  {
    code: 'NIST_SSDF',
    name: 'NIST SSDF',
    fullName: 'NIST SP 800-218 — Secure Software Development Framework (SSDF)',
    type: 'international_standard',
    expected: 40,
    description: 'NIST-Framework fuer sichere Softwareentwicklung. Definiert Praktiken und Aufgaben in vier Gruppen: Prepare, Protect, Produce, Respond. Weit verbreitet als Referenz fuer Software Supply Chain Security.',
    relevantFor: ['Softwareentwickler', 'DevSecOps', 'IT-Sicherheit', 'Compliance-Manager'],
    keyTopics: ['SSDF', 'Secure SDLC', 'Software Supply Chain', 'Vulnerability Management', 'Code Review'],
    effectiveDate: '3. Februar 2022'
  },
  {
    code: 'NIST_CSF_2',
    name: 'NIST CSF 2.0',
    fullName: 'NIST Cybersecurity Framework (CSF) 2.0',
    type: 'international_standard',
    expected: 50,
    description: 'Version 2.0 des NIST Cybersecurity Framework. Neue Kernfunktion "Govern" ergaenzt Identify, Protect, Detect, Respond, Recover. Erweitert den Anwendungsbereich ueber kritische Infrastruktur hinaus auf alle Organisationen.',
    relevantFor: ['CISO', 'IT-Sicherheit', 'Risikomanagement', 'Geschaeftsfuehrung', 'Alle Branchen'],
    keyTopics: ['Govern', 'Identify', 'Protect', 'Detect', 'Respond', 'Recover', 'Cybersecurity'],
    effectiveDate: '26. Februar 2024'
  },
  {
    code: 'OECD_AI_PRINCIPLES',
    name: 'OECD AI Principles',
    fullName: 'OECD Recommendation on Artificial Intelligence (AI Principles)',
    type: 'international_standard',
    expected: 20,
    description: 'OECD-Empfehlung zu Kuenstlicher Intelligenz. Definiert fuenf Prinzipien fuer verantwortungsvolle KI: Inklusives Wachstum, Menschenzentrierte Werte, Transparenz, Robustheit und Rechenschaftspflicht. Von 46 Laendern angenommen.',
    relevantFor: ['KI-Entwickler', 'Policy-Maker', 'Ethik-Kommissionen', 'Geschaeftsfuehrung'],
    keyTopics: ['AI Ethics', 'Transparenz', 'Accountability', 'Trustworthy AI', 'Human-Centered AI'],
    effectiveDate: '22. Mai 2019'
  },
  {
    code: 'EU_IFRS',
    name: 'EU-IFRS',
    fullName: 'Verordnung (EU) 2023/1803 — International Financial Reporting Standards',
    type: 'eu_regulation',
    expected: 500,
    description: 'Konsolidierte Fassung der von der EU uebernommenen IFRS/IAS/IFRIC/SIC. Rechtsverbindlich fuer boersennotierte EU-Unternehmen. Enthalt IFRS 1-17, IAS 1-41, IFRIC 1-23 und SIC 7-32 in der EU-endorsed Fassung (Stand Okt 2023). ACHTUNG: Neuere IASB-Standards sind moeglicherweise noch nicht EU-endorsed.',
    relevantFor: ['Rechnungswesen', 'Wirtschaftspruefer', 'boersennotierte Unternehmen', 'Finanzberichterstattung', 'CFO'],
    keyTopics: ['IFRS 16 Leasing', 'IFRS 9 Finanzinstrumente', 'IAS 1 Darstellung', 'IFRS 15 Erloese', 'IFRS 17 Versicherungsvertraege', 'Konsolidierung'],
    effectiveDate: '16. Oktober 2023'
  },
  {
    code: 'EFRAG_ENDORSEMENT',
    name: 'EFRAG Endorsement Status',
    fullName: 'EFRAG EU Endorsement Status Report (Dezember 2025)',
    type: 'eu_guideline',
    expected: 30,
    description: 'Uebersicht des European Financial Reporting Advisory Group (EFRAG) ueber den EU-Endorsement-Stand aller IFRS/IAS-Standards. Zeigt welche Standards von der EU uebernommen wurden und welche noch ausstehend sind. Relevant fuer internationale Ausschreibungen und Compliance-Pruefung.',
    relevantFor: ['Rechnungswesen', 'Wirtschaftspruefer', 'Compliance Officer', 'internationale Ausschreibungen'],
    keyTopics: ['EU Endorsement', 'IFRS 18', 'IFRS S1/S2 Sustainability', 'Endorsement Status', 'IASB Updates'],
    effectiveDate: '18. Dezember 2025'
  },
]

// Source URLs for original documents (click to view original)
const REGULATION_SOURCES: Record<string, string> = {
  // EU Verordnungen/Richtlinien (EUR-Lex)
  GDPR: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32016R0679',
  EPRIVACY: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32002L0058',
  SCC: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32021D0914',
  DPF: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32023D1795',
  AIACT: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32024R1689',
  CRA: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32024R2847',
  NIS2: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32022L2555',
  EUCSA: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32019R0881',
  DATAACT: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32023R2854',
  DGA: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32022R0868',
  DSA: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32022R2065',
  EAA: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32019L0882',
  DSM: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32019L0790',
  PLD: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32024L2853',
  GPSR: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32023R0988',
  DORA: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32022R2554',
  PSD2: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32015L2366',
  AMLR: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32024R1624',
  MiCA: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32023R1114',
  EHDS: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32025R0327',
  SCC_FULL_TEXT: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32021D0914',
  E_COMMERCE_RL: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32000L0031',
  VERBRAUCHERRECHTE_RL: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32011L0083',
  DIGITALE_INHALTE_RL: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32019L0770',
  DMA: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32022R1925',
  MACHINERY_REG: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32023R1230',
  BLUE_GUIDE: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:52022XC0629(04)',
  EU_IFRS: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32023R1803',
  // EDPB Guidelines
  EDPB_GUIDELINES_2_2019: 'https://www.edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-22019-processing-personal-data-under-article-61b_en',
  EDPB_GUIDELINES_3_2019: 'https://www.edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-32019-processing-personal-data-through-video_en',
  EDPB_GUIDELINES_5_2020: 'https://www.edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-052020-consent-under-regulation-2016679_en',
  EDPB_GUIDELINES_7_2020: 'https://www.edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-072020-concepts-controller-and-processor-gdpr_en',
  EDPB_GUIDELINES_1_2022: 'https://www.edpb.europa.eu/our-work-tools/our-documents/guidelines/guidelines-042022-calculation-administrative-fines-under-gdpr_en',
  // BSI Technische Richtlinien
  'BSI-TR-03161-1': 'https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03161/BSI-TR-03161-1.html',
  'BSI-TR-03161-2': 'https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03161/BSI-TR-03161-2.html',
  'BSI-TR-03161-3': 'https://www.bsi.bund.de/SharedDocs/Downloads/DE/BSI/Publikationen/TechnischeRichtlinien/TR03161/BSI-TR-03161-3.html',
  // Nationale Datenschutzgesetze
  AT_DSG: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10001597',
  BDSG_FULL: 'https://www.gesetze-im-internet.de/bdsg_2018/',
  CH_DSG: 'https://www.fedlex.admin.ch/eli/cc/2022/491/de',
  LI_DSG: 'https://www.gesetze.li/konso/2018.272',
  BE_DPA_LAW: 'https://www.autoriteprotectiondonnees.be/citoyen/la-loi-du-30-juillet-2018',
  NL_UAVG: 'https://wetten.overheid.nl/BWBR0040940/',
  FR_CNIL_GUIDE: 'https://www.cnil.fr/fr/rgpd-par-ou-commencer',
  ES_LOPDGDD: 'https://www.boe.es/buscar/act.php?id=BOE-A-2018-16673',
  IT_CODICE_PRIVACY: 'https://www.garanteprivacy.it/home/docweb/-/docweb-display/docweb/9042678',
  IE_DPA_2018: 'https://www.irishstatutebook.ie/eli/2018/act/7/enacted/en/html',
  UK_DPA_2018: 'https://www.legislation.gov.uk/ukpga/2018/12/contents',
  UK_GDPR: 'https://www.legislation.gov.uk/eur/2016/679/contents',
  NO_PERSONOPPLYSNINGSLOVEN: 'https://lovdata.no/dokument/NL/lov/2018-06-15-38',
  SE_DATASKYDDSLAG: 'https://www.riksdagen.se/sv/dokument-och-lagar/dokument/svensk-forfattningssamling/lag-2018218-med-kompletterande-bestammelser_sfs-2018-218/',
  FI_TIETOSUOJALAKI: 'https://www.finlex.fi/fi/laki/ajantasa/2018/20181050',
  PL_UODO: 'https://isap.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20180001000',
  CZ_ZOU: 'https://www.zakonyprolidi.cz/cs/2019-110',
  HU_INFOTV: 'https://net.jogtar.hu/jogszabaly?docid=a1100112.tv',
  LU_DPA_LAW: 'https://legilux.public.lu/eli/etat/leg/loi/2018/08/01/a686/jo',
  DK_DATABESKYTTELSESLOVEN: 'https://www.retsinformation.dk/eli/lta/2018/502',
  // Deutschland — Weitere Gesetze
  TDDDG: 'https://www.gesetze-im-internet.de/tdddg/',
  DE_DDG: 'https://www.gesetze-im-internet.de/ddg/',
  DE_BGB_AGB: 'https://www.gesetze-im-internet.de/bgb/__305.html',
  DE_EGBGB: 'https://www.gesetze-im-internet.de/bgbeg/art_246.html',
  DE_UWG: 'https://www.gesetze-im-internet.de/uwg_2004/',
  DE_HGB_RET: 'https://www.gesetze-im-internet.de/hgb/__257.html',
  DE_AO_RET: 'https://www.gesetze-im-internet.de/ao_1977/__147.html',
  DE_TKG: 'https://www.gesetze-im-internet.de/tkg_2021/',
  DE_PANGV: 'https://www.gesetze-im-internet.de/pangv_2022/',
  DE_DLINFOV: 'https://www.gesetze-im-internet.de/dlinfov/',
  DE_BETRVG: 'https://www.gesetze-im-internet.de/betrvg/__87.html',
  DE_GESCHGEHG: 'https://www.gesetze-im-internet.de/geschgehg/',
  DE_BSIG: 'https://www.gesetze-im-internet.de/bsig_2009/',
  DE_USTG_RET: 'https://www.gesetze-im-internet.de/ustg_1980/__14b.html',
  // Oesterreich — Weitere Gesetze
  AT_ECG: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=20001703',
  AT_TKG: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=20007898',
  AT_KSCHG: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10002462',
  AT_FAGG: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=20008783',
  AT_UGB_RET: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10001702',
  AT_BAO_RET: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10003940',
  AT_MEDIENG: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10000719',
  AT_ABGB_AGB: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10001622',
  AT_UWG: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10002665',
  // Schweiz
  CH_DSV: 'https://www.fedlex.admin.ch/eli/cc/2022/568/de',
  CH_OR_AGB: 'https://www.fedlex.admin.ch/eli/cc/27/317_321_377/de',
  CH_UWG: 'https://www.fedlex.admin.ch/eli/cc/1988/223_223_223/de',
  CH_FMG: 'https://www.fedlex.admin.ch/eli/cc/1997/2187_2187_2187/de',
  CH_GEBUV: 'https://www.fedlex.admin.ch/eli/cc/2002/249/de',
  CH_ZERTES: 'https://www.fedlex.admin.ch/eli/cc/2016/752/de',
  CH_ZGB_PERS: 'https://www.fedlex.admin.ch/eli/cc/24/233_245_233/de',
  // Industrie-Compliance
  ENISA_SECURE_BY_DESIGN: 'https://www.enisa.europa.eu/publications/secure-development-best-practices',
  ENISA_SUPPLY_CHAIN: 'https://www.enisa.europa.eu/publications/threat-landscape-for-supply-chain-attacks',
  NIST_SSDF: 'https://csrc.nist.gov/pubs/sp/800/218/final',
  NIST_CSF_2: 'https://www.nist.gov/cyberframework',
  OECD_AI_PRINCIPLES: 'https://legalinstruments.oecd.org/en/instruments/OECD-LEGAL-0449',
  // IFRS / EFRAG
  EU_IFRS_DE: 'https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:32023R1803',
  EU_IFRS_EN: 'https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32023R1803',
  EFRAG_ENDORSEMENT: 'https://www.efrag.org/activities/endorsement-status-report',
  // Full-text Datenschutzgesetz AT
  AT_DSG_FULL: 'https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10001597',
}

// License info for each regulation
const REGULATION_LICENSES: Record<string, { license: string; licenseNote: string }> = {
  GDPR: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk der EU — frei verwendbar' },
  EPRIVACY: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  TDDDG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  SCC: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Durchfuehrungsbeschluss — amtliches Werk' },
  DPF: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Angemessenheitsbeschluss — amtliches Werk' },
  AIACT: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  CRA: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  NIS2: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  EUCSA: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  DATAACT: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  DGA: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  DSA: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  EAA: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  DSM: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  PLD: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  GPSR: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  'BSI-TR-03161-1': { license: 'DL-DE-BY-2.0', licenseNote: 'Datenlizenz Deutschland — Namensnennung 2.0' },
  'BSI-TR-03161-2': { license: 'DL-DE-BY-2.0', licenseNote: 'Datenlizenz Deutschland — Namensnennung 2.0' },
  'BSI-TR-03161-3': { license: 'DL-DE-BY-2.0', licenseNote: 'Datenlizenz Deutschland — Namensnennung 2.0' },
  DORA: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  PSD2: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  AMLR: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  MiCA: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  EHDS: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  // National Data Protection Laws
  AT_DSG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  BDSG_FULL: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  CH_DSG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweiz — frei verwendbar' },
  LI_DSG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Liechtenstein — frei verwendbar' },
  BE_DPA_LAW: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Belgien — frei verwendbar' },
  NL_UAVG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Niederlande — frei verwendbar' },
  FR_CNIL_GUIDE: { license: 'PUBLIC_DOMAIN', licenseNote: 'CNIL — oeffentliches Dokument' },
  ES_LOPDGDD: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Spanien (BOE) — frei verwendbar' },
  IT_CODICE_PRIVACY: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Italien — frei verwendbar' },
  IE_DPA_2018: { license: 'OGL-3.0', licenseNote: 'Open Government Licence v3.0 — Ireland' },
  UK_DPA_2018: { license: 'OGL-3.0', licenseNote: 'Open Government Licence v3.0 — UK' },
  UK_GDPR: { license: 'OGL-3.0', licenseNote: 'Open Government Licence v3.0 — UK' },
  NO_PERSONOPPLYSNINGSLOVEN: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Norwegen — frei verwendbar' },
  SE_DATASKYDDSLAG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweden — frei verwendbar' },
  FI_TIETOSUOJALAKI: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Finnland — frei verwendbar' },
  PL_UODO: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Polen — frei verwendbar' },
  CZ_ZOU: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Tschechien — frei verwendbar' },
  HU_INFOTV: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Ungarn — frei verwendbar' },
  SCC_FULL_TEXT: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Durchfuehrungsbeschluss — amtliches Werk' },
  EDPB_GUIDELINES_2_2019: { license: 'EDPB-LICENSE', licenseNote: 'EDPB Document License' },
  EDPB_GUIDELINES_3_2019: { license: 'EDPB-LICENSE', licenseNote: 'EDPB Document License' },
  EDPB_GUIDELINES_5_2020: { license: 'EDPB-LICENSE', licenseNote: 'EDPB Document License' },
  EDPB_GUIDELINES_7_2020: { license: 'EDPB-LICENSE', licenseNote: 'EDPB Document License' },
  // Industrie-Compliance (2026-02-28)
  MACHINERY_REG: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  BLUE_GUIDE: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Leitfaden — amtliches Werk der Kommission' },
  ENISA_SECURE_BY_DESIGN: { license: 'CC-BY-4.0', licenseNote: 'ENISA Publication — CC BY 4.0' },
  ENISA_SUPPLY_CHAIN: { license: 'CC-BY-4.0', licenseNote: 'ENISA Publication — CC BY 4.0' },
  NIST_SSDF: { license: 'PUBLIC_DOMAIN', licenseNote: 'US Government Work — Public Domain' },
  NIST_CSF_2: { license: 'PUBLIC_DOMAIN', licenseNote: 'US Government Work — Public Domain' },
  OECD_AI_PRINCIPLES: { license: 'PUBLIC_DOMAIN', licenseNote: 'OECD Legal Instrument — Reuse Notice' },
  // EU-IFRS / EFRAG (2026-02-28)
  EU_IFRS_DE: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  EU_IFRS_EN: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
  EFRAG_ENDORSEMENT: { license: 'PUBLIC_DOMAIN', licenseNote: 'EFRAG — oeffentliches Dokument' },
  // DACH National Laws — Deutschland
  DE_DDG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_BGB_AGB: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_EGBGB: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_UWG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_HGB_RET: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_AO_RET: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_TKG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_PANGV: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsche Verordnung — amtliches Werk (§5 UrhG)' },
  DE_DLINFOV: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsche Verordnung — amtliches Werk (§5 UrhG)' },
  DE_BETRVG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_GESCHGEHG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_BSIG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  DE_USTG_RET: { license: 'PUBLIC_DOMAIN', licenseNote: 'Deutsches Bundesgesetz — amtliches Werk (§5 UrhG)' },
  // DACH National Laws — Oesterreich
  AT_ECG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  AT_TKG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  AT_KSCHG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  AT_FAGG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  AT_UGB_RET: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  AT_BAO_RET: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  AT_MEDIENG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  AT_ABGB_AGB: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  AT_UWG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Oesterreich — frei verwendbar' },
  // DACH National Laws — Schweiz
  CH_DSV: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweiz — frei verwendbar' },
  CH_OR_AGB: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweiz — frei verwendbar' },
  CH_UWG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweiz — frei verwendbar' },
  CH_FMG: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweiz — frei verwendbar' },
  CH_GEBUV: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweiz — frei verwendbar' },
  CH_ZERTES: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweiz — frei verwendbar' },
  CH_ZGB_PERS: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Schweiz — frei verwendbar' },
  // 3 fehlgeschlagene Quellen (korrigiert)
  LU_DPA_LAW: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Luxemburg — frei verwendbar' },
  DK_DATABESKYTTELSESLOVEN: { license: 'PUBLIC_DOMAIN', licenseNote: 'Amtliches Werk Daenemark — frei verwendbar' },
  EDPB_GUIDELINES_1_2022: { license: 'EDPB-LICENSE', licenseNote: 'EDPB Document License' },
  // Neue EU-Richtlinien (Februar 2026 ingestiert)
  E_COMMERCE_RL: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  VERBRAUCHERRECHTE_RL: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  DIGITALE_INHALTE_RL: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Richtlinie — amtliches Werk' },
  DMA: { license: 'PUBLIC_DOMAIN', licenseNote: 'EU-Verordnung — amtliches Werk' },
}

// REGULATIONS_IN_RAG is imported from ./rag-constants.ts

// Helper: Check if regulation is in RAG
const isInRag = (code: string): boolean => code in REGULATIONS_IN_RAG

// Helper: Get known chunk count for a regulation
const getKnownChunks = (code: string): number => REGULATIONS_IN_RAG[code]?.chunks || 0

// Known collection totals (updated: 2026-03-05)
// Note: bp_compliance_datenschutz expanded via edpb-crawler.py (55 EDPB/WP29/EDPS documents).
// bp_dsfa_corpus expanded with 20 DSFA Muss-Listen (BfDI + DSK + 16 Bundeslaender).
const COLLECTION_TOTALS = {
  bp_compliance_gesetze: 58304,
  bp_compliance_ce: 18183,
  bp_legal_templates: 7689,
  bp_compliance_datenschutz: 17459,
  bp_dsfa_corpus: 8666,
  bp_compliance_recht: 1425,
  bp_nibis_eh: 7996,
  total_legal: 76487, // gesetze + ce
  total_all: 119722,
}

// License display labels
const LICENSE_LABELS: Record<string, string> = {
  PUBLIC_DOMAIN: 'Public Domain',
  'DL-DE-BY-2.0': 'DL-DE-BY 2.0',
  'CC-BY-4.0': 'CC BY 4.0',
  'EDPB-LICENSE': 'EDPB License',
  'OGL-3.0': 'OGL v3.0',
  PROPRIETARY: 'Proprietaer',
}

const TYPE_COLORS: Record<string, string> = {
  eu_regulation: 'bg-blue-100 text-blue-700',
  eu_directive: 'bg-purple-100 text-purple-700',
  de_law: 'bg-yellow-100 text-yellow-700',
  at_law: 'bg-red-100 text-red-700',
  ch_law: 'bg-rose-100 text-rose-700',
  bsi_standard: 'bg-green-100 text-green-700',
  national_law: 'bg-orange-100 text-orange-700',
  eu_guideline: 'bg-teal-100 text-teal-700',
}

const TYPE_LABELS: Record<string, string> = {
  eu_regulation: 'EU-VO',
  eu_directive: 'EU-RL',
  de_law: 'DE-Gesetz',
  at_law: 'AT-Gesetz',
  ch_law: 'CH-Gesetz',
  bsi_standard: 'BSI',
  national_law: 'Nat. Gesetz',
  eu_guideline: 'EDPB-GL',
}

// Industry/Sector definitions for the regulation map
const INDUSTRIES = [
  { id: 'all', name: 'Alle Unternehmen', icon: '🏢', description: 'Grundlegende Anforderungen fuer alle' },
  { id: 'health', name: 'Gesundheitswesen', icon: '🏥', description: 'Krankenhaeuser, DiGA, Medizintechnik' },
  { id: 'finance', name: 'Finanzsektor', icon: '🏦', description: 'Banken, Versicherungen, Zahlungsdienstleister' },
  { id: 'ecommerce', name: 'E-Commerce', icon: '🛒', description: 'Online-Shops, Marktplaetze' },
  { id: 'tech', name: 'Technologie/Software', icon: '💻', description: 'Software-Entwickler, SaaS, Cloud' },
  { id: 'iot', name: 'IoT/Hardware', icon: '📱', description: 'Geraetehersteller, Smart Devices' },
  { id: 'ai', name: 'KI-Anbieter', icon: '🤖', description: 'KI-Entwickler und -Anwender' },
  { id: 'kritis', name: 'Kritische Infrastruktur', icon: '⚡', description: 'Energie, Wasser, Transport' },
  { id: 'media', name: 'Medien/Plattformen', icon: '📺', description: 'Social Media, Content-Plattformen' },
  { id: 'public', name: 'Oeffentlicher Sektor', icon: '🏛️', description: 'Behoerden, Verwaltung' },
]

// Mapping: Which regulations apply to which industries
const INDUSTRY_REGULATION_MAP: Record<string, string[]> = {
  all: ['GDPR', 'EPRIVACY', 'TDDDG'],
  health: ['GDPR', 'TDDDG', 'BSI-TR-03161-1', 'BSI-TR-03161-2', 'BSI-TR-03161-3', 'NIS2', 'AIACT', 'PLD', 'EHDS'],
  finance: ['GDPR', 'TDDDG', 'NIS2', 'EUCSA', 'DSA', 'AIACT', 'DPF', 'DORA', 'PSD2', 'AMLR', 'MiCA'],
  ecommerce: ['GDPR', 'TDDDG', 'DSA', 'GPSR', 'EAA', 'PLD', 'DPF', 'PSD2'],
  tech: ['GDPR', 'TDDDG', 'CRA', 'AIACT', 'DPF', 'SCC', 'DATAACT', 'DSM', 'MiCA'],
  iot: ['GDPR', 'CRA', 'GPSR', 'PLD', 'DATAACT', 'AIACT'],
  ai: ['GDPR', 'AIACT', 'PLD', 'DSM', 'DATAACT'],
  kritis: ['GDPR', 'NIS2', 'EUCSA', 'CRA', 'AIACT', 'DORA'],
  media: ['GDPR', 'TDDDG', 'DSA', 'DSM', 'EAA', 'AIACT'],
  public: ['GDPR', 'NIS2', 'EUCSA', 'EAA', 'DGA', 'AIACT', 'EHDS'],
}

// Thematic groupings showing overlaps
const THEMATIC_GROUPS = [
  {
    id: 'datenschutz',
    name: 'Datenschutz & Privacy',
    color: 'bg-blue-500',
    regulations: ['GDPR', 'EPRIVACY', 'TDDDG', 'SCC', 'DPF'],
    description: 'Schutz personenbezogener Daten, Einwilligung, Betroffenenrechte'
  },
  {
    id: 'cybersecurity',
    name: 'Cybersicherheit',
    color: 'bg-red-500',
    regulations: ['NIS2', 'EUCSA', 'CRA', 'BSI-TR-03161-1', 'BSI-TR-03161-2', 'BSI-TR-03161-3', 'DORA'],
    description: 'IT-Sicherheit, Risikomanagement, Incident Response'
  },
  {
    id: 'ai',
    name: 'Kuenstliche Intelligenz',
    color: 'bg-purple-500',
    regulations: ['AIACT', 'PLD', 'GPSR'],
    description: 'KI-Regulierung, Hochrisiko-Systeme, Haftung'
  },
  {
    id: 'digital-markets',
    name: 'Digitale Maerkte & Plattformen',
    color: 'bg-green-500',
    regulations: ['DSA', 'DGA', 'DATAACT', 'DSM'],
    description: 'Plattformregulierung, Datenzugang, Urheberrecht'
  },
  {
    id: 'product-safety',
    name: 'Produktsicherheit & Haftung',
    color: 'bg-orange-500',
    regulations: ['CRA', 'PLD', 'GPSR', 'EAA'],
    description: 'Sicherheitsanforderungen, CE-Kennzeichnung, Barrierefreiheit'
  },
  {
    id: 'finance',
    name: 'Finanzmarktregulierung',
    color: 'bg-emerald-500',
    regulations: ['DORA', 'PSD2', 'AMLR', 'MiCA'],
    description: 'Zahlungsdienste, Krypto-Assets, Geldwaeschebekaempfung, digitale Resilienz'
  },
  {
    id: 'health',
    name: 'Gesundheitsdaten',
    color: 'bg-pink-500',
    regulations: ['EHDS', 'BSI-TR-03161-1', 'BSI-TR-03161-2', 'BSI-TR-03161-3'],
    description: 'Gesundheitsdatenraum, DiGA-Sicherheit, Patientenrechte'
  },
]

// Key overlaps and intersections
const KEY_INTERSECTIONS = [
  {
    regulations: ['GDPR', 'AIACT'],
    topic: 'KI und personenbezogene Daten',
    description: 'Automatisierte Entscheidungen, Profiling, Erklaerbarkeit'
  },
  {
    regulations: ['NIS2', 'CRA'],
    topic: 'Cybersicherheit von Produkten',
    description: 'Sicherheitsanforderungen ueber den gesamten Lebenszyklus'
  },
  {
    regulations: ['AIACT', 'PLD'],
    topic: 'KI-Haftung',
    description: 'Wer haftet, wenn KI Schaeden verursacht?'
  },
  {
    regulations: ['DSA', 'GDPR'],
    topic: 'Plattform-Transparenz',
    description: 'Inhaltsmoderation und Datenschutz'
  },
  {
    regulations: ['DATAACT', 'GDPR'],
    topic: 'Datenzugang vs. Datenschutz',
    description: 'Balance zwischen Datenteilung und Privacy'
  },
  {
    regulations: ['CRA', 'GPSR'],
    topic: 'Digitale Produktsicherheit',
    description: 'Hardware mit Software-Komponenten'
  },
]

// Future outlook - proposed and discussed regulations
const FUTURE_OUTLOOK = [
  {
    id: 'digital-omnibus',
    name: 'EU Digital Omnibus',
    status: 'proposed',
    statusLabel: 'Vorgeschlagen Nov 2025',
    expectedDate: '2026/2027',
    description: 'Umfassendes Vereinfachungspaket fuer AI Act, DSGVO und Cybersicherheit. Ziel: 5 Mrd. EUR Einsparung bei Verwaltungskosten.',
    keyChanges: [
      'AI Act: Verschiebung Hochrisiko-Pflichten um bis zu 16 Monate (bis Dez 2027)',
      'AI Act: Vereinfachte Dokumentation fuer KMU und Small Midcaps',
      'AI Act: EU-weite regulatorische Sandbox fuer KI-Tests',
      'DSGVO: Cookie-Banner-Reform - Berechtigtes Interesse statt nur Einwilligung',
      'DSGVO: Automatische Privacy-Signale via Browser statt Pop-ups',
      'Cybersecurity: Single Entry Point fuer Meldepflichten'
    ],
    affectedRegulations: ['AIACT', 'GDPR', 'NIS2', 'CRA', 'EUCSA'],
    source: 'https://digital-strategy.ec.europa.eu/en/library/digital-omnibus-ai-regulation-proposal'
  },
  {
    id: 'sustainability-omnibus',
    name: 'EU Nachhaltigkeits-Omnibus',
    status: 'agreed',
    statusLabel: 'Einigung Dez 2025',
    expectedDate: 'Q1 2026',
    description: 'Drastische Reduzierung der Nachhaltigkeits-Berichtspflichten. Anwendungsbereich wird stark eingeschraenkt.',
    keyChanges: [
      'CSRD: Nur noch Unternehmen >1.000 MA und >450 Mio EUR Umsatz berichtspflichtig',
      'CSRD: Betroffene Unternehmen sinken von 50.000 auf ca. 5.000 in der EU',
      'CSRD: Verschiebung Welle 2+3 um 2 Jahre (auf Geschaeftsjahr 2027)',
      'CSDDD: Nur noch Unternehmen >5.000 MA und >1,5 Mrd EUR Umsatz',
      'CSDDD: Sorgfaltspflichten nur noch fuer Tier-1-Lieferanten',
      'CSDDD: Pruefung nur noch alle 5 Jahre statt jaehrlich'
    ],
    affectedRegulations: ['CSRD', 'CSDDD', 'EU-Taxonomie'],
    source: 'https://kpmg-law.de/erste-omnibus-verordnung-soll-die-pflichten-der-csddd-csrd-und-eu-taxonomie-lockern/'
  },
  {
    id: 'eprivacy-withdrawal',
    name: 'ePrivacy-Verordnung',
    status: 'withdrawn',
    statusLabel: 'Zurueckgezogen Feb 2025',
    expectedDate: 'Unbekannt',
    description: 'Nach 9 Jahren Verhandlung hat die EU-Kommission den Vorschlag zurueckgezogen. Die ePrivacy-Richtlinie bleibt in Kraft, Cookie-Reform kommt via DSGVO/Digital Omnibus.',
    keyChanges: [
      'Urspruenglicher Vorschlag: Einheitliche EU-Cookie-Regeln',
      'Urspruenglicher Vorschlag: Strikte Tracking-Einwilligung',
      'Status: ePrivacy-Richtlinie + TDDDG bleiben gueltig',
      'Zukunft: Cookie-Reform wird Teil der DSGVO-Aenderungen'
    ],
    affectedRegulations: ['EPRIVACY', 'TDDDG', 'GDPR'],
    source: 'https://netzpolitik.org/2025/cookie-banner-und-online-tracking-eu-kommission-beerdigt-plaene-fuer-eprivacy-verordnung/'
  },
  {
    id: 'ai-liability',
    name: 'KI-Haftungsrichtlinie',
    status: 'pending',
    statusLabel: 'In Verhandlung',
    expectedDate: '2026',
    description: 'Ergaenzt den AI Act um zivilrechtliche Haftungsregeln. Erleichtert Geschaedigten die Beweisfuehrung bei KI-Schaeden.',
    keyChanges: [
      'Beweislasterleichterung bei KI-verursachten Schaeden',
      'Offenlegungspflichten fuer KI-Anbieter im Schadensfall',
      'Verknuepfung mit Produkthaftungsrichtlinie'
    ],
    affectedRegulations: ['AIACT', 'PLD'],
    source: 'https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:52022PC0496'
  },
]

// Additional regulations that could be added to RAG (publicly available, commercial use permitted)
// Regulations now integrated in main RAG (previously listed as candidates)
const INTEGRATED_REGULATIONS = [
  {
    code: 'DORA',
    name: 'Digital Operational Resilience Act',
    status: 'integrated',
    addedDate: 'Januar 2025',
    description: 'Jetzt im RAG verfuegbar - Finanzsektor IT-Resilienz'
  },
  {
    code: 'MiCA',
    name: 'Markets in Crypto-Assets',
    status: 'integrated',
    addedDate: 'Januar 2025',
    description: 'Jetzt im RAG verfuegbar - Krypto-Regulierung'
  },
  {
    code: 'PSD2',
    name: 'Payment Services Directive 2',
    status: 'integrated',
    addedDate: 'Januar 2025',
    description: 'Jetzt im RAG verfuegbar - Zahlungsdienste'
  },
  {
    code: 'AMLR',
    name: 'AML-Verordnung',
    status: 'integrated',
    addedDate: 'Januar 2025',
    description: 'Jetzt im RAG verfuegbar - Geldwaeschebekaempfung'
  },
  {
    code: 'EHDS',
    name: 'European Health Data Space',
    status: 'integrated',
    addedDate: 'Januar 2025',
    description: 'Jetzt im RAG verfuegbar - Gesundheitsdatenraum'
  },
]

// Potential future regulations (not yet integrated)
const ADDITIONAL_REGULATIONS = [
  {
    code: 'PSD3',
    name: 'Payment Services Directive 3',
    fullName: 'Richtlinie zur dritten Zahlungsdiensterichtlinie (Entwurf)',
    type: 'eu_directive',
    status: 'proposed',
    effectiveDate: 'Voraussichtlich 2026',
    description: 'Modernisierung der Zahlungsdienste-Regulierung. Staerkerer Verbraucherschutz, Open Banking 2.0, Betrugsbekaempfung. Ersetzt dann PSD2.',
    relevantFor: ['Banken', 'Zahlungsdienstleister', 'Fintechs', 'E-Commerce'],
    celex: '52023PC0366',
    priority: 'medium'
  },
  {
    code: 'AMLD6',
    name: 'AML-Richtlinie 6',
    fullName: 'Richtlinie (EU) 2024/1640 - 6. Geldwaescherichtlinie',
    type: 'eu_directive',
    status: 'active',
    effectiveDate: '10. Juli 2027 (Umsetzung)',
    description: 'Ergaenzt die AML-Verordnung. Nationale Umsetzungsvorschriften, strafrechtliche Sanktionen, AMLA-Behoerde.',
    relevantFor: ['Banken', 'Krypto-Anbieter', 'Immobilienmakler', 'Gluecksspielanbieter'],
    celex: '32024L1640',
    priority: 'medium'
  },
  {
    code: 'FIDA',
    name: 'Financial Data Access',
    fullName: 'Verordnung zum Zugang zu Finanzdaten (Entwurf)',
    type: 'eu_regulation',
    status: 'proposed',
    effectiveDate: 'Voraussichtlich 2027',
    description: 'Open Finance Framework - erweitert PSD2-Open-Banking auf Versicherungen, Investitionen, Kredite.',
    relevantFor: ['Banken', 'Versicherungen', 'Fintechs', 'Datenaggregatoren'],
    celex: '52023PC0360',
    priority: 'medium'
  },
]

// Legal basis for using EUR-Lex content
const LEGAL_BASIS_INFO = {
  title: 'Rechtliche Grundlage fuer RAG-Nutzung',
  summary: 'EU-Rechtstexte auf EUR-Lex sind oeffentliche amtliche Dokumente und duerfen frei verwendet werden.',
  details: [
    {
      aspect: 'EUR-Lex Dokumente',
      status: 'Erlaubt',
      explanation: 'Offizielle EU-Gesetzestexte, Richtlinien und Verordnungen sind gemeinfrei (Public Domain) und duerfen frei reproduziert und kommerziell genutzt werden.'
    },
    {
      aspect: 'Text-und-Data-Mining (TDM)',
      status: 'Erlaubt',
      explanation: 'Art. 4 der DSM-Richtlinie (2019/790) erlaubt TDM fuer kommerzielle Zwecke, sofern kein Opt-out des Rechteinhabers vorliegt. Fuer amtliche Texte gilt kein Opt-out.'
    },
    {
      aspect: 'AI Act Anforderungen',
      status: 'Beachten',
      explanation: 'Art. 53 AI Act verlangt von GPAI-Anbietern die Einhaltung des Urheberrechts. Fuer oeffentliche Rechtstexte unproblematisch.'
    },
    {
      aspect: 'BSI-Richtlinien',
      status: 'Erlaubt',
      explanation: 'BSI-Publikationen sind oeffentlich zugaenglich und duerfen fuer Compliance-Zwecke verwendet werden.'
    },
  ]
}

export default function RAGPage() {
  const [activeTab, setActiveTab] = useState<TabId>('overview')
  const [collectionStatus, setCollectionStatus] = useState<CollectionStatus | null>(null)
  const [loading, setLoading] = useState(true)
  const [searchQuery, setSearchQuery] = useState('')
  const [searchResults, setSearchResults] = useState<SearchResult[]>([])
  const [searching, setSearching] = useState(false)
  const [selectedRegulations, setSelectedRegulations] = useState<string[]>([])
  const [ingestionRunning, setIngestionRunning] = useState(false)
  const [ingestionLog, setIngestionLog] = useState<string[]>([])
  const [pipelineState, setPipelineState] = useState<PipelineState | null>(null)
  const [pipelineLoading, setPipelineLoading] = useState(false)
  const [pipelineStarting, setPipelineStarting] = useState(false)
  const [expandedRegulation, setExpandedRegulation] = useState<string | null>(null)
  const [autoRefresh, setAutoRefresh] = useState(true)
  const [elapsedTime, setElapsedTime] = useState<string>('')

  // Chunk browser state is now in ChunkBrowserQA component

  // DSFA corpus state
  const [dsfaSources, setDsfaSources] = useState<DsfaSource[]>([])
  const [dsfaStatus, setDsfaStatus] = useState<DsfaCorpusStatus | null>(null)
  const [dsfaLoading, setDsfaLoading] = useState(false)
  const [regulationCategory, setRegulationCategory] = useState<RegulationCategory>('regulations')
  const [expandedDsfaSource, setExpandedDsfaSource] = useState<string | null>(null)

  // Data tab state
  const [customDocuments, setCustomDocuments] = useState<CustomDocument[]>([])
  const [uploadFile, setUploadFile] = useState<File | null>(null)
  const [uploadTitle, setUploadTitle] = useState('')
  const [uploadCode, setUploadCode] = useState('')
  const [uploading, setUploading] = useState(false)
  const [linkUrl, setLinkUrl] = useState('')
  const [linkTitle, setLinkTitle] = useState('')
  const [linkCode, setLinkCode] = useState('')
  const [addingLink, setAddingLink] = useState(false)

  const fetchStatus = useCallback(async () => {
    setLoading(true)
    try {
      const res = await fetch(`${API_PROXY}?action=status`)
      if (res.ok) {
        const data = await res.json()
        setCollectionStatus(data)
      }
    } catch (error) {
      console.error('Failed to fetch status:', error)
    } finally {
      setLoading(false)
    }
  }, [])

  const fetchPipeline = useCallback(async () => {
    setPipelineLoading(true)
    try {
      const res = await fetch(`${API_PROXY}?action=pipeline-checkpoints`)
      if (res.ok) {
        const data = await res.json()
        setPipelineState(data)
      }
    } catch (error) {
      console.error('Failed to fetch pipeline:', error)
    } finally {
      setPipelineLoading(false)
    }
  }, [])

  const fetchDsfaStatus = useCallback(async () => {
    setDsfaLoading(true)
    try {
      const [statusRes, sourcesRes] = await Promise.all([
        fetch(`${DSFA_API_PROXY}?action=status`),
        fetch(`${DSFA_API_PROXY}?action=sources`),
      ])
      if (statusRes.ok) {
        const data = await statusRes.json()
        setDsfaStatus(data)
      }
      if (sourcesRes.ok) {
        const data = await sourcesRes.json()
        setDsfaSources(data.sources || data || [])
      }
    } catch (error) {
      console.error('Failed to fetch DSFA status:', error)
    } finally {
      setDsfaLoading(false)
    }
  }, [])

  const fetchCustomDocuments = useCallback(async () => {
    try {
      const res = await fetch(`${API_PROXY}?action=custom-documents`)
      if (res.ok) {
        const data = await res.json()
        setCustomDocuments(data.documents || [])
      }
    } catch (error) {
      console.error('Failed to fetch custom documents:', error)
    }
  }, [])

  const handleUpload = async () => {
    if (!uploadFile || !uploadTitle || !uploadCode) return

    setUploading(true)
    try {
      const formData = new FormData()
      formData.append('file', uploadFile)
      formData.append('title', uploadTitle)
      formData.append('code', uploadCode)
      formData.append('document_type', 'custom')

      const res = await fetch(`${API_PROXY}?action=upload`, {
        method: 'POST',
        body: formData,
      })

      if (res.ok) {
        setUploadFile(null)
        setUploadTitle('')
        setUploadCode('')
        fetchCustomDocuments()
        fetchStatus()
      }
    } catch (error) {
      console.error('Upload failed:', error)
    } finally {
      setUploading(false)
    }
  }

  const handleAddLink = async () => {
    if (!linkUrl || !linkTitle || !linkCode) return

    setAddingLink(true)
    try {
      const res = await fetch(`${API_PROXY}?action=add-link`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          url: linkUrl,
          title: linkTitle,
          code: linkCode,
          document_type: 'custom',
        }),
      })

      if (res.ok) {
        setLinkUrl('')
        setLinkTitle('')
        setLinkCode('')
        fetchCustomDocuments()
      }
    } catch (error) {
      console.error('Add link failed:', error)
    } finally {
      setAddingLink(false)
    }
  }

  const handleDeleteDocument = async (docId: string) => {
    try {
      const res = await fetch(`${API_PROXY}?action=delete-document&docId=${docId}`, {
        method: 'DELETE',
      })
      if (res.ok) {
        fetchCustomDocuments()
        fetchStatus()
      }
    } catch (error) {
      console.error('Delete failed:', error)
    }
  }

  const handleStartPipeline = async (skipIngestion: boolean = false) => {
    setPipelineStarting(true)
    try {
      const res = await fetch(`${API_PROXY}?action=start-pipeline`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          force_reindex: false,
          skip_ingestion: skipIngestion,
        }),
      })

      if (res.ok) {
        // Wait a moment then refresh pipeline status
        setTimeout(() => {
          fetchPipeline()
          setPipelineStarting(false)
        }, 2000)
      } else {
        setPipelineStarting(false)
      }
    } catch (error) {
      console.error('Failed to start pipeline:', error)
      setPipelineStarting(false)
    }
  }

  useEffect(() => {
    fetchStatus()
    fetchDsfaStatus()
  }, [fetchStatus, fetchDsfaStatus])

  useEffect(() => {
    if (activeTab === 'pipeline') {
      fetchPipeline()
    }
  }, [activeTab, fetchPipeline])

  useEffect(() => {
    if (activeTab === 'data') {
      fetchCustomDocuments()
    }
  }, [activeTab, fetchCustomDocuments])

  // Auto-refresh pipeline status when running
  useEffect(() => {
    if (activeTab !== 'pipeline' || !autoRefresh) return

    const isRunning = pipelineState?.status === 'running'

    if (isRunning) {
      const interval = setInterval(() => {
        fetchPipeline()
        fetchStatus() // Also refresh chunk counts
      }, 5000) // Every 5 seconds

      return () => clearInterval(interval)
    }
  }, [activeTab, autoRefresh, pipelineState?.status, fetchPipeline, fetchStatus])

  // Update elapsed time
  useEffect(() => {
    if (!pipelineState?.started_at || pipelineState?.status !== 'running') {
      setElapsedTime('')
      return
    }

    const updateElapsed = () => {
      const start = new Date(pipelineState.started_at!).getTime()
      const now = Date.now()
      const diff = Math.floor((now - start) / 1000)

      const hours = Math.floor(diff / 3600)
      const minutes = Math.floor((diff % 3600) / 60)
      const seconds = diff % 60

      if (hours > 0) {
        setElapsedTime(`${hours}h ${minutes}m ${seconds}s`)
      } else if (minutes > 0) {
        setElapsedTime(`${minutes}m ${seconds}s`)
      } else {
        setElapsedTime(`${seconds}s`)
      }
    }

    updateElapsed()
    const interval = setInterval(updateElapsed, 1000)
    return () => clearInterval(interval)
  }, [pipelineState?.started_at, pipelineState?.status])

  // Chunk browser functions are now in ChunkBrowserQA component

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

    setSearching(true)
    try {
      const params = new URLSearchParams({
        action: 'search',
        query: searchQuery,
        top_k: '5',
      })
      if (selectedRegulations.length > 0) {
        params.append('regulations', selectedRegulations.join(','))
      }

      const res = await fetch(`${API_PROXY}?${params}`)
      if (res.ok) {
        const data = await res.json()
        setSearchResults(data.results || [])
      }
    } catch (error) {
      console.error('Search failed:', error)
    } finally {
      setSearching(false)
    }
  }

  const triggerIngestion = async () => {
    setIngestionRunning(true)
    setIngestionLog(['Starte Re-Ingestion aller 19 Regulierungen...'])

    try {
      const res = await fetch(`${API_PROXY}?action=ingest`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ force: true }),
      })

      if (res.ok) {
        const data = await res.json()
        setIngestionLog((prev) => [...prev, 'Ingestion gestartet. Job-ID: ' + (data.job_id || 'N/A')])
        // Poll for status
        const checkStatus = setInterval(async () => {
          try {
            const statusRes = await fetch(`${API_PROXY}?action=ingestion-status`)
            if (statusRes.ok) {
              const statusData = await statusRes.json()
              if (statusData.completed) {
                clearInterval(checkStatus)
                setIngestionRunning(false)
                setIngestionLog((prev) => [...prev, 'Ingestion abgeschlossen!'])
                fetchStatus()
              } else if (statusData.current_regulation) {
                setIngestionLog((prev) => [
                  ...prev,
                  `Verarbeite: ${statusData.current_regulation} (${statusData.processed}/${statusData.total})`,
                ])
              }
            }
          } catch {
            // Ignore polling errors
          }
        }, 5000)
      } else {
        setIngestionLog((prev) => [...prev, 'Fehler: ' + res.statusText])
        setIngestionRunning(false)
      }
    } catch (error) {
      setIngestionLog((prev) => [...prev, 'Fehler: ' + String(error)])
      setIngestionRunning(false)
    }
  }

  const getRegulationChunks = (code: string): number => {
    return collectionStatus?.regulations?.[code] || 0
  }

  const getTotalChunks = (): number => {
    return collectionStatus?.totalPoints || 0
  }

  const tabs = [
    { id: 'overview' as TabId, name: 'Uebersicht', icon: '📊' },
    { id: 'regulations' as TabId, name: 'Regulierungen', icon: '📜' },
    { id: 'map' as TabId, name: 'Landkarte', icon: '🗺️' },
    { id: 'search' as TabId, name: 'Suche', icon: '🔍' },
    { id: 'chunks' as TabId, name: 'Chunk-Browser', icon: '🧩' },
    { id: 'data' as TabId, name: 'Daten', icon: '📁' },
    { id: 'ingestion' as TabId, name: 'Ingestion', icon: '⚙️' },
    { id: 'pipeline' as TabId, name: 'Pipeline', icon: '🔄' },
  ]

  return (
    <div className="min-h-screen bg-slate-50">
      {/* Header */}
      <div className="bg-white border-b px-6 py-4">
        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-2xl font-bold text-slate-900">Daten & RAG</h1>
            <p className="text-slate-600">Legal Corpus Management fuer Compliance</p>
          </div>
          <Link
            href="/ai"
            className="flex items-center gap-2 text-slate-600 hover:text-slate-800"
          >
            <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
            </svg>
            KI & Automatisierung
          </Link>
        </div>
      </div>

      <div className="p-6">
        {/* Page Purpose */}
        <PagePurpose
          title="Daten & RAG"
          purpose={`Verwalten und durchsuchen Sie 7 RAG-Collections mit ${REGULATIONS.length} Regulierungen (${Object.keys(REGULATIONS_IN_RAG).length} im RAG). Legal Corpus, DSFA Corpus (70+ Quellen), NiBiS EH (Bildungsinhalte) und Legal Templates. Teil der KI-Daten-Pipeline fuer Compliance und Klausur-Korrektur.`}
          audience={['DSB', 'Compliance Officer', 'Entwickler']}
          gdprArticles={['§5 UrhG (Amtliche Werke)', 'Art. 5 DSGVO (Rechenschaftspflicht)']}
          architecture={{
            services: ['klausur-service (Python)', 'embedding-service (BGE-M3)', 'Qdrant (Vector DB)'],
            databases: ['Qdrant: bp_legal_corpus, bp_dsfa_corpus, bp_nibis_eh, bp_legal_templates'],
          }}
          relatedPages={[
            { name: 'RAG Pipeline', href: '/ai/rag-pipeline', description: 'Neue Dokumente indexieren' },
            { name: 'Klausur-Korrektur', href: '/ai/klausur-korrektur', description: 'RAG-Suche nutzen' },
            { name: 'OCR-Labeling', href: '/ai/ocr-labeling', description: 'Ground Truth erstellen' },
            { name: 'Compliance Hub', href: '/sdk/compliance-hub', description: 'Compliance-Dashboard' },
          ]}
        />

        {/* AI Module Sidebar - Desktop: Fixed, Mobile: FAB + Drawer */}
        <AIModuleSidebarResponsive currentModule="rag" />

        {/* RAG Collections Stats */}
        <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
          <div className="bg-white rounded-xl p-4 border border-slate-200">
            <p className="text-xs font-medium text-blue-600 uppercase mb-1">Legal Corpus</p>
            <p className="text-2xl font-bold text-slate-900">{COLLECTION_TOTALS.total_legal.toLocaleString()}</p>
            <p className="text-xs text-slate-500">Chunks &middot; {Object.keys(REGULATIONS_IN_RAG).length}/{REGULATIONS.length} im RAG</p>
          </div>
          <div className="bg-white rounded-xl p-4 border border-slate-200">
            <p className="text-xs font-medium text-purple-600 uppercase mb-1">DSFA Corpus</p>
            <p className="text-2xl font-bold text-slate-900">{dsfaLoading ? '-' : (dsfaStatus?.total_chunks || 0).toLocaleString()}</p>
            <p className="text-xs text-slate-500">Chunks &middot; {dsfaSources.length || '~70'} Quellen</p>
          </div>
          <div className="bg-white rounded-xl p-4 border border-slate-200">
            <p className="text-xs font-medium text-emerald-600 uppercase mb-1">NiBiS EH</p>
            <p className="text-2xl font-bold text-slate-900">7.996</p>
            <p className="text-xs text-slate-500">Chunks &middot; Bildungs-Erwartungshorizonte</p>
          </div>
          <div className="bg-white rounded-xl p-4 border border-slate-200">
            <p className="text-xs font-medium text-orange-600 uppercase mb-1">Legal Templates</p>
            <p className="text-2xl font-bold text-slate-900">7.689</p>
            <p className="text-xs text-slate-500">Chunks &middot; Dokumentvorlagen</p>
          </div>
        </div>

        {/* Tabs */}
        <div className="flex gap-1 mb-6 border-b border-slate-200">
          {tabs.map((tab) => (
            <button
              key={tab.id}
              onClick={() => setActiveTab(tab.id)}
              className={`px-4 py-2 text-sm font-medium border-b-2 -mb-px transition-colors ${
                activeTab === tab.id
                  ? 'border-teal-600 text-teal-600'
                  : 'border-transparent text-slate-500 hover:text-slate-700'
              }`}
            >
              <span className="mr-2">{tab.icon}</span>
              {tab.name}
            </button>
          ))}
        </div>

        {/* Tab Content */}
        {activeTab === 'overview' && (
          <div className="space-y-6">
            {/* RAG Categories Overview */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">RAG-Kategorien</h3>
              <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                <button
                  onClick={() => { setRegulationCategory('regulations'); setActiveTab('regulations') }}
                  className="p-4 rounded-lg border border-blue-200 bg-blue-50 hover:bg-blue-100 transition-colors text-left"
                >
                  <p className="text-xs font-medium text-blue-600 uppercase">Gesetze & Regulierungen</p>
                  <p className="text-2xl font-bold text-slate-900 mt-1">{COLLECTION_TOTALS.total_legal.toLocaleString()}</p>
                  <p className="text-xs text-slate-500 mt-1">{Object.keys(REGULATIONS_IN_RAG).length}/{REGULATIONS.length} im RAG</p>
                </button>
                <button
                  onClick={() => { setRegulationCategory('dsfa'); setActiveTab('regulations') }}
                  className="p-4 rounded-lg border border-purple-200 bg-purple-50 hover:bg-purple-100 transition-colors text-left"
                >
                  <p className="text-xs font-medium text-purple-600 uppercase">DSFA Corpus</p>
                  <p className="text-2xl font-bold text-slate-900 mt-1">{dsfaLoading ? '-' : (dsfaStatus?.total_chunks || 0).toLocaleString()}</p>
                  <p className="text-xs text-slate-500 mt-1">{dsfaSources.length || '~70'} Quellen (WP248, DSK, Gesetze)</p>
                </button>
                <div className="p-4 rounded-lg border border-emerald-200 bg-emerald-50 text-left">
                  <p className="text-xs font-medium text-emerald-600 uppercase">NiBiS EH</p>
                  <p className="text-2xl font-bold text-slate-900 mt-1">7.996</p>
                  <p className="text-xs text-slate-500 mt-1">Chunks &middot; Bildungs-Erwartungshorizonte</p>
                </div>
                <div className="p-4 rounded-lg border border-orange-200 bg-orange-50 text-left">
                  <p className="text-xs font-medium text-orange-600 uppercase">Legal Templates</p>
                  <p className="text-2xl font-bold text-slate-900 mt-1">7.689</p>
                  <p className="text-xs text-slate-500 mt-1">Chunks &middot; Dokumentvorlagen (VVT, TOM, DSFA)</p>
                </div>
              </div>
            </div>

            {/* Quick Stats per Type */}
            <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
              {Object.entries(TYPE_LABELS).map(([type, label]) => {
                const regs = REGULATIONS.filter((r) => r.type === type)
                const inRagCount = regs.filter((r) => isInRag(r.code)).length
                const totalChunks = regs.reduce((sum, r) => sum + getKnownChunks(r.code), 0)
                return (
                  <div key={type} className="bg-white rounded-xl p-4 border border-slate-200">
                    <div className="flex items-center gap-2 mb-2">
                      <span className={`px-2 py-0.5 text-xs rounded ${TYPE_COLORS[type]}`}>{label}</span>
                      <span className="text-slate-500 text-sm">{inRagCount}/{regs.length} im RAG</span>
                    </div>
                    <p className="text-xl font-bold text-slate-900">{totalChunks.toLocaleString()} Chunks</p>
                  </div>
                )
              })}
            </div>

            {/* Top Regulations */}
            <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
              <div className="px-4 py-3 border-b bg-slate-50">
                <h3 className="font-semibold text-slate-900">Top Regulierungen (nach Chunks)</h3>
              </div>
              <div className="divide-y">
                {[...REGULATIONS].sort((a, b) => getKnownChunks(b.code) - getKnownChunks(a.code))
                  .slice(0, 10)
                  .map((reg) => {
                    const chunks = getKnownChunks(reg.code)
                    return (
                      <div key={reg.code} className="px-4 py-3 flex items-center justify-between">
                        <div className="flex items-center gap-3">
                          {isInRag(reg.code) ? (
                            <span className="text-green-500 text-sm">✓</span>
                          ) : (
                            <span className="text-red-400 text-sm">✗</span>
                          )}
                          <span className={`px-2 py-0.5 text-xs rounded ${TYPE_COLORS[reg.type]}`}>
                            {TYPE_LABELS[reg.type]}
                          </span>
                          <span className="font-medium text-slate-900">{reg.name}</span>
                          <span className="text-slate-500 text-sm">({reg.code})</span>
                        </div>
                        <span className={`font-bold ${chunks > 0 ? 'text-teal-600' : 'text-slate-300'}`}>{chunks > 0 ? chunks.toLocaleString() + ' Chunks' : '—'}</span>
                      </div>
                    )
                  })}
              </div>
            </div>
          </div>
        )}

        {activeTab === 'regulations' && (
          <div className="space-y-4">
            {/* Category Filter */}
            <div className="flex items-center gap-2 flex-wrap">
              <button
                onClick={() => setRegulationCategory('regulations')}
                className={`px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${
                  regulationCategory === 'regulations'
                    ? 'bg-blue-100 text-blue-700 ring-2 ring-blue-300'
                    : 'bg-white text-slate-600 border border-slate-200 hover:bg-slate-50'
                }`}
              >
                Gesetze & Regulierungen ({REGULATIONS.length})
              </button>
              <button
                onClick={() => setRegulationCategory('dsfa')}
                className={`px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${
                  regulationCategory === 'dsfa'
                    ? 'bg-purple-100 text-purple-700 ring-2 ring-purple-300'
                    : 'bg-white text-slate-600 border border-slate-200 hover:bg-slate-50'
                }`}
              >
                DSFA Quellen ({dsfaSources.length || '~70'})
              </button>
              <button
                onClick={() => setRegulationCategory('nibis')}
                className={`px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${
                  regulationCategory === 'nibis'
                    ? 'bg-emerald-100 text-emerald-700 ring-2 ring-emerald-300'
                    : 'bg-white text-slate-600 border border-slate-200 hover:bg-slate-50'
                }`}
              >
                NiBiS Dokumente
              </button>
              <button
                onClick={() => setRegulationCategory('templates')}
                className={`px-3 py-1.5 text-sm font-medium rounded-lg transition-colors ${
                  regulationCategory === 'templates'
                    ? 'bg-orange-100 text-orange-700 ring-2 ring-orange-300'
                    : 'bg-white text-slate-600 border border-slate-200 hover:bg-slate-50'
                }`}
              >
                Templates & Vorlagen
              </button>
            </div>

            {/* Regulations Table (existing) */}
            {regulationCategory === 'regulations' && (
          <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
            <div className="px-4 py-3 border-b bg-slate-50 flex items-center justify-between">
              <h3 className="font-semibold text-slate-900">
                Alle {REGULATIONS.length} Regulierungen
                <span className="ml-2 text-sm font-normal text-slate-500">
                  ({REGULATIONS.filter(r => isInRag(r.code)).length} im RAG,{' '}
                  {REGULATIONS.filter(r => !isInRag(r.code)).length} ausstehend)
                </span>
              </h3>
              <button
                onClick={fetchStatus}
                className="text-sm text-teal-600 hover:text-teal-700"
              >
                Aktualisieren
              </button>
            </div>
            <div className="overflow-x-auto">
              <table className="w-full">
                <thead className="bg-slate-50 border-b">
                  <tr>
                    <th className="px-4 py-3 text-center text-xs font-medium text-slate-500 uppercase w-12">RAG</th>
                    <th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase">Code</th>
                    <th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase">Typ</th>
                    <th className="px-4 py-3 text-left text-xs font-medium text-slate-500 uppercase">Name</th>
                    <th className="px-4 py-3 text-right text-xs font-medium text-slate-500 uppercase">Chunks</th>
                    <th className="px-4 py-3 text-right text-xs font-medium text-slate-500 uppercase">Erwartet</th>
                    <th className="px-4 py-3 text-center text-xs font-medium text-slate-500 uppercase">Status</th>
                  </tr>
                </thead>
                <tbody className="divide-y">
                  {REGULATIONS.map((reg) => {
                    const chunks = getKnownChunks(reg.code)
                    const inRag = isInRag(reg.code)
                    let statusColor = inRag ? 'text-green-500' : 'text-red-500'
                    let statusIcon = inRag ? '✓' : '❌'
                    const isExpanded = expandedRegulation === reg.code

                    return (
                      <React.Fragment key={reg.code}>
                        <tr
                          onClick={() => setExpandedRegulation(isExpanded ? null : reg.code)}
                          className="hover:bg-slate-50 cursor-pointer transition-colors"
                        >
                          <td className="px-4 py-3 text-center">
                            {isInRag(reg.code) ? (
                              <span className="inline-flex items-center justify-center w-6 h-6 bg-green-100 text-green-600 rounded-full text-xs font-bold" title="Im RAG vorhanden">✓</span>
                            ) : (
                              <span className="inline-flex items-center justify-center w-6 h-6 bg-red-50 text-red-400 rounded-full text-xs font-bold" title="Nicht im RAG">✗</span>
                            )}
                          </td>
                          <td className="px-4 py-3 font-mono font-medium text-teal-600">
                            <span className="inline-flex items-center gap-2">
                              <span className={`transform transition-transform ${isExpanded ? 'rotate-90' : ''}`}>▶</span>
                              {reg.code}
                            </span>
                          </td>
                          <td className="px-4 py-3">
                            <span className={`px-2 py-0.5 text-xs rounded ${TYPE_COLORS[reg.type]}`}>
                              {TYPE_LABELS[reg.type]}
                            </span>
                          </td>
                          <td className="px-4 py-3 text-slate-900">{reg.name}</td>
                          <td className="px-4 py-3 text-right font-bold">
                            <span className={chunks > 0 && chunks < 10 && reg.expected >= 10 ? 'text-amber-600' : ''}>
                              {chunks.toLocaleString()}
                              {chunks > 0 && chunks < 10 && reg.expected >= 10 && (
                                <span className="ml-1 inline-block w-4 h-4 text-[10px] leading-4 text-center bg-amber-100 text-amber-700 rounded-full" title="Verdaechtig niedrig — Ingestion pruefen">⚠</span>
                              )}
                            </span>
                          </td>
                          <td className="px-4 py-3 text-right text-slate-500">{reg.expected}</td>
                          <td className={`px-4 py-3 text-center ${statusColor}`}>{statusIcon}</td>
                        </tr>
                        {isExpanded && (
                          <tr key={`${reg.code}-detail`} className="bg-slate-50">
                            <td colSpan={7} className="px-4 py-4">
                              <div className="bg-white rounded-lg border border-slate-200 p-4 space-y-3">
                                <div>
                                  <h4 className="font-semibold text-slate-900 mb-1">{reg.fullName}</h4>
                                  <p className="text-sm text-slate-600">{reg.description}</p>
                                </div>
                                <div className="grid grid-cols-1 md:grid-cols-2 gap-4 pt-2 border-t border-slate-100">
                                  <div>
                                    <p className="text-xs font-medium text-slate-500 uppercase mb-1">Relevant fuer</p>
                                    <div className="flex flex-wrap gap-1">
                                      {reg.relevantFor.map((item, idx) => (
                                        <span key={idx} className="px-2 py-0.5 text-xs bg-slate-100 text-slate-600 rounded">
                                          {item}
                                        </span>
                                      ))}
                                    </div>
                                  </div>
                                  <div>
                                    <p className="text-xs font-medium text-slate-500 uppercase mb-1">Kernthemen</p>
                                    <div className="flex flex-wrap gap-1">
                                      {reg.keyTopics.map((topic, idx) => (
                                        <span key={idx} className="px-2 py-0.5 text-xs bg-teal-50 text-teal-700 rounded">
                                          {topic}
                                        </span>
                                      ))}
                                    </div>
                                  </div>
                                </div>
                                <div className="flex items-center justify-between pt-2 border-t border-slate-100 text-xs text-slate-500">
                                  <div className="flex items-center gap-4">
                                    <span>In Kraft seit: {reg.effectiveDate}</span>
                                    {REGULATION_LICENSES[reg.code] && (
                                      <span className="flex items-center gap-1">
                                        <span className="px-1.5 py-0.5 bg-slate-100 text-slate-600 rounded text-[10px] font-medium">
                                          {LICENSE_LABELS[REGULATION_LICENSES[reg.code].license] || REGULATION_LICENSES[reg.code].license}
                                        </span>
                                        <span className="text-slate-400">{REGULATION_LICENSES[reg.code].licenseNote}</span>
                                      </span>
                                    )}
                                  </div>
                                  <div className="flex items-center gap-3">
                                    {REGULATION_SOURCES[reg.code] && (
                                      <a
                                        href={REGULATION_SOURCES[reg.code]}
                                        target="_blank"
                                        rel="noopener noreferrer"
                                        onClick={(e) => e.stopPropagation()}
                                        className="text-blue-600 hover:text-blue-700 font-medium"
                                      >
                                        Originalquelle →
                                      </a>
                                    )}
                                    <button
                                      onClick={(e) => {
                                        e.stopPropagation()
                                        setActiveTab('chunks')
                                      }}
                                      className="text-teal-600 hover:text-teal-700 font-medium"
                                    >
                                      In Chunks suchen →
                                    </button>
                                  </div>
                                </div>
                              </div>
                            </td>
                          </tr>
                        )}
                      </React.Fragment>
                    )
                  })}
                </tbody>
              </table>
            </div>
          </div>
            )}

            {/* DSFA Sources */}
            {regulationCategory === 'dsfa' && (
              <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
                <div className="px-4 py-3 border-b bg-slate-50 flex items-center justify-between">
                  <div>
                    <h3 className="font-semibold text-slate-900">DSFA Quellen ({dsfaSources.length || '~70'})</h3>
                    <p className="text-xs text-slate-500">WP248, DSK Kurzpapiere, Muss-Listen, nationale Datenschutzgesetze</p>
                  </div>
                  <button
                    onClick={fetchDsfaStatus}
                    className="text-sm text-teal-600 hover:text-teal-700"
                  >
                    Aktualisieren
                  </button>
                </div>
                {dsfaLoading ? (
                  <div className="p-8 text-center text-slate-500">Lade DSFA-Quellen...</div>
                ) : dsfaSources.length === 0 ? (
                  <div className="p-8 text-center text-slate-500">
                    <p className="mb-2">Keine DSFA-Quellen vom Backend geladen.</p>
                    <p className="text-xs">Endpunkt: <code className="bg-slate-100 px-1 rounded">/api/dsfa-corpus?action=sources</code></p>
                  </div>
                ) : (
                  <div className="divide-y">
                    {dsfaSources.map((source) => {
                      const isExpanded = expandedDsfaSource === source.source_code
                      const typeColors: Record<string, string> = {
                        regulation: 'bg-blue-100 text-blue-700',
                        legislation: 'bg-indigo-100 text-indigo-700',
                        guideline: 'bg-teal-100 text-teal-700',
                        checklist: 'bg-yellow-100 text-yellow-700',
                        standard: 'bg-green-100 text-green-700',
                        methodology: 'bg-purple-100 text-purple-700',
                        specification: 'bg-orange-100 text-orange-700',
                        catalog: 'bg-pink-100 text-pink-700',
                        guidance: 'bg-cyan-100 text-cyan-700',
                      }
                      return (
                        <React.Fragment key={source.source_code}>
                          <div
                            onClick={() => setExpandedDsfaSource(isExpanded ? null : source.source_code)}
                            className="px-4 py-3 hover:bg-slate-50 cursor-pointer transition-colors flex items-center justify-between"
                          >
                            <div className="flex items-center gap-3">
                              <span className={`transform transition-transform text-xs ${isExpanded ? 'rotate-90' : ''}`}>▶</span>
                              <span className="font-mono text-sm text-purple-600 font-medium">{source.source_code}</span>
                              <span className={`px-2 py-0.5 text-xs rounded ${typeColors[source.document_type] || 'bg-slate-100 text-slate-600'}`}>
                                {source.document_type}
                              </span>
                              <span className="text-sm text-slate-900">{source.name}</span>
                            </div>
                            <div className="flex items-center gap-3">
                              <span className="px-1.5 py-0.5 text-[10px] font-medium bg-slate-100 text-slate-500 rounded uppercase">
                                {source.language}
                              </span>
                              {source.chunk_count != null && (
                                <span className="text-sm font-bold text-purple-600">{source.chunk_count} Chunks</span>
                              )}
                            </div>
                          </div>
                          {isExpanded && (
                            <div className="px-4 pb-4 bg-slate-50">
                              <div className="bg-white rounded-lg border border-slate-200 p-4 space-y-3">
                                <div>
                                  <h4 className="font-semibold text-slate-900 mb-1">{source.full_name || source.name}</h4>
                                  {source.organization && (
                                    <p className="text-sm text-slate-600">Organisation: {source.organization}</p>
                                  )}
                                </div>
                                <div className="flex items-center gap-4 pt-2 border-t border-slate-100 text-xs text-slate-500">
                                  <span className="flex items-center gap-1">
                                    <span className="px-1.5 py-0.5 bg-slate-100 text-slate-600 rounded text-[10px] font-medium">
                                      {LICENSE_LABELS[source.license_code] || source.license_code}
                                    </span>
                                    <span className="text-slate-400">{source.attribution_text}</span>
                                  </span>
                                </div>
                                {source.source_url && (
                                  <div className="text-xs">
                                    <a
                                      href={source.source_url}
                                      target="_blank"
                                      rel="noopener noreferrer"
                                      className="text-teal-600 hover:underline"
                                      onClick={(e) => e.stopPropagation()}
                                    >
                                      Quelle: {source.source_url}
                                    </a>
                                  </div>
                                )}
                              </div>
                            </div>
                          )}
                        </React.Fragment>
                      )
                    })}
                  </div>
                )}
              </div>
            )}

            {/* NiBiS Dokumente (info only) */}
            {regulationCategory === 'nibis' && (
              <div className="bg-white rounded-xl border border-slate-200 p-6">
                <div className="flex items-center gap-3 mb-4">
                  <div className="w-10 h-10 rounded-lg bg-emerald-100 flex items-center justify-center text-xl">📚</div>
                  <div>
                    <h3 className="font-semibold text-slate-900">NiBiS Erwartungshorizonte</h3>
                    <p className="text-sm text-slate-500">Collection: <code className="bg-slate-100 px-1 rounded">bp_nibis_eh</code></p>
                  </div>
                </div>
                <div className="grid grid-cols-3 gap-4 mb-4">
                  <div className="bg-emerald-50 rounded-lg p-4 border border-emerald-200">
                    <p className="text-sm text-emerald-600 font-medium">Chunks</p>
                    <p className="text-2xl font-bold text-slate-900">7.996</p>
                  </div>
                  <div className="bg-emerald-50 rounded-lg p-4 border border-emerald-200">
                    <p className="text-sm text-emerald-600 font-medium">Vector Size</p>
                    <p className="text-2xl font-bold text-slate-900">1024</p>
                  </div>
                  <div className="bg-emerald-50 rounded-lg p-4 border border-emerald-200">
                    <p className="text-sm text-emerald-600 font-medium">Typ</p>
                    <p className="text-2xl font-bold text-slate-900">BGE-M3</p>
                  </div>
                </div>
                <p className="text-sm text-slate-600">
                  Bildungsinhalte aus dem Niedersaechsischen Bildungsserver (NiBiS). Enthaelt Erwartungshorizonte fuer
                  verschiedene Faecher und Schulformen. Wird ueber die Klausur-Korrektur fuer EH-Matching genutzt.
                  Diese Daten sind nicht direkt compliance-relevant.
                </p>
              </div>
            )}

            {/* Templates (info only) */}
            {regulationCategory === 'templates' && (
              <div className="bg-white rounded-xl border border-slate-200 p-6">
                <div className="flex items-center gap-3 mb-4">
                  <div className="w-10 h-10 rounded-lg bg-orange-100 flex items-center justify-center text-xl">📋</div>
                  <div>
                    <h3 className="font-semibold text-slate-900">Legal Templates & Vorlagen</h3>
                    <p className="text-sm text-slate-500">Collection: <code className="bg-slate-100 px-1 rounded">bp_legal_templates</code></p>
                  </div>
                </div>
                <div className="grid grid-cols-3 gap-4 mb-4">
                  <div className="bg-orange-50 rounded-lg p-4 border border-orange-200">
                    <p className="text-sm text-orange-600 font-medium">Chunks</p>
                    <p className="text-2xl font-bold text-slate-900">7.689</p>
                  </div>
                  <div className="bg-orange-50 rounded-lg p-4 border border-orange-200">
                    <p className="text-sm text-orange-600 font-medium">Vector Size</p>
                    <p className="text-2xl font-bold text-slate-900">1024</p>
                  </div>
                  <div className="bg-orange-50 rounded-lg p-4 border border-orange-200">
                    <p className="text-sm text-orange-600 font-medium">Typ</p>
                    <p className="text-2xl font-bold text-slate-900">BGE-M3</p>
                  </div>
                </div>
                <p className="text-sm text-slate-600">
                  Vorlagen fuer VVT (Verzeichnis von Verarbeitungstaetigkeiten), TOM (Technisch-Organisatorische Massnahmen),
                  DSFA-Berichte und weitere Compliance-Dokumente. Werden vom AI Compliance SDK fuer die Dokumentgenerierung genutzt.
                </p>
              </div>
            )}
          </div>
        )}

        {activeTab === 'map' && (
          <div className="space-y-6">
            {/* Industry Filter */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">Regulierungen nach Branche</h3>
              <p className="text-sm text-slate-500 mb-4">
                Waehlen Sie Ihre Branche, um relevante Regulierungen zu sehen.
              </p>
              <div className="grid grid-cols-2 md:grid-cols-5 gap-3">
                {INDUSTRIES.map((industry) => {
                  const regs = INDUSTRY_REGULATION_MAP[industry.id] || []
                  return (
                    <button
                      key={industry.id}
                      onClick={() => {
                        setExpandedRegulation(industry.id === expandedRegulation ? null : industry.id)
                      }}
                      className={`p-4 rounded-lg border text-left transition-all ${
                        expandedRegulation === industry.id
                          ? 'border-teal-500 bg-teal-50 ring-2 ring-teal-200'
                          : 'border-slate-200 hover:border-slate-300 hover:bg-slate-50'
                      }`}
                    >
                      <div className="text-2xl mb-2">{industry.icon}</div>
                      <div className="font-medium text-slate-900 text-sm">{industry.name}</div>
                      <div className="text-xs text-slate-500 mt-1">{regs.length} Regulierungen</div>
                    </button>
                  )
                })}
              </div>

              {/* Selected Industry Details */}
              {expandedRegulation && INDUSTRIES.find(i => i.id === expandedRegulation) && (
                <div className="mt-6 p-4 bg-slate-50 rounded-lg">
                  {(() => {
                    const industry = INDUSTRIES.find(i => i.id === expandedRegulation)!
                    const regCodes = INDUSTRY_REGULATION_MAP[industry.id] || []
                    const regs = REGULATIONS.filter(r => regCodes.includes(r.code))
                    return (
                      <>
                        <div className="flex items-center gap-3 mb-4">
                          <span className="text-3xl">{industry.icon}</span>
                          <div>
                            <h4 className="font-semibold text-slate-900">{industry.name}</h4>
                            <p className="text-sm text-slate-500">{industry.description}</p>
                          </div>
                        </div>
                        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
                          {regs.map((reg) => {
                            const regInRag = isInRag(reg.code)
                            return (
                            <div
                              key={reg.code}
                              className={`bg-white p-3 rounded-lg border ${regInRag ? 'border-green-200' : 'border-slate-200'}`}
                            >
                              <div className="flex items-center gap-2 mb-1">
                                <span className={`px-2 py-0.5 text-xs rounded ${TYPE_COLORS[reg.type]}`}>
                                  {reg.code}
                                </span>
                                {regInRag ? (
                                  <span className="px-1.5 py-0.5 text-[10px] font-bold bg-green-100 text-green-600 rounded">RAG</span>
                                ) : (
                                  <span className="px-1.5 py-0.5 text-[10px] font-bold bg-red-50 text-red-400 rounded">✗</span>
                                )}
                              </div>
                              <div className="font-medium text-sm text-slate-900">{reg.name}</div>
                              <div className="text-xs text-slate-500 mt-1 line-clamp-2">{reg.description}</div>
                            </div>
                            )
                          })}
                        </div>
                      </>
                    )
                  })()}
                </div>
              )}
            </div>

            {/* Thematic Groups */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">Thematische Cluster</h3>
              <p className="text-sm text-slate-500 mb-4">
                Regulierungen gruppiert nach Themenbereichen - zeigt Ueberschneidungen.
              </p>
              <div className="space-y-4">
                {THEMATIC_GROUPS.map((group) => (
                  <div key={group.id} className="border border-slate-200 rounded-lg overflow-hidden">
                    <div className={`${group.color} px-4 py-2 text-white font-medium flex items-center justify-between`}>
                      <span>{group.name}</span>
                      <span className="text-sm opacity-80">{group.regulations.length} Regulierungen</span>
                    </div>
                    <div className="p-4">
                      <p className="text-sm text-slate-600 mb-3">{group.description}</p>
                      <div className="flex flex-wrap gap-2">
                        {group.regulations.map((code) => {
                          const reg = REGULATIONS.find(r => r.code === code)
                          const codeInRag = isInRag(code)
                          return (
                            <span
                              key={code}
                              className={`px-3 py-1.5 rounded-full text-sm font-medium cursor-pointer ${
                                codeInRag
                                  ? 'bg-green-100 text-green-700 hover:bg-green-200'
                                  : 'bg-slate-100 text-slate-700 hover:bg-slate-200'
                              }`}
                              onClick={() => {
                                setActiveTab('regulations')
                                setExpandedRegulation(code)
                              }}
                              title={`${reg?.fullName || code}${codeInRag ? ' (im RAG)' : ' (nicht im RAG)'}`}
                            >
                              {codeInRag ? '✓ ' : '✗ '}{code}
                            </span>
                          )
                        })}
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {/* Key Intersections */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">Wichtige Schnittstellen</h3>
              <p className="text-sm text-slate-500 mb-4">
                Bereiche, in denen sich mehrere Regulierungen ueberschneiden und zusammenwirken.
              </p>
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {KEY_INTERSECTIONS.map((intersection, idx) => (
                  <div key={idx} className="bg-gradient-to-br from-slate-50 to-slate-100 rounded-lg p-4 border border-slate-200">
                    <div className="flex flex-wrap gap-1 mb-2">
                      {intersection.regulations.map((code) => (
                        <span
                          key={code}
                          className={`px-2 py-0.5 text-xs font-medium rounded ${
                            isInRag(code)
                              ? 'bg-green-100 text-green-700'
                              : 'bg-red-50 text-red-500'
                          }`}
                        >
                          {isInRag(code) ? '✓ ' : '✗ '}{code}
                        </span>
                      ))}
                    </div>
                    <div className="font-medium text-slate-900 text-sm mb-1">{intersection.topic}</div>
                    <div className="text-xs text-slate-500">{intersection.description}</div>
                  </div>
                ))}
              </div>
            </div>

            {/* Regulation Matrix */}
            <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
              <div className="px-4 py-3 border-b bg-slate-50">
                <h3 className="font-semibold text-slate-900">Branchen-Regulierungs-Matrix</h3>
                <p className="text-sm text-slate-500">Welche Regulierungen in welchen Branchen gelten</p>
              </div>
              <div className="overflow-x-auto">
                <table className="w-full text-xs">
                  <thead className="bg-slate-50 border-b">
                    <tr>
                      <th className="px-2 py-2 text-left font-medium text-slate-500 sticky left-0 bg-slate-50">Regulierung</th>
                      {INDUSTRIES.filter(i => i.id !== 'all').map((industry) => (
                        <th key={industry.id} className="px-2 py-2 text-center font-medium text-slate-500 min-w-[60px]">
                          <div className="flex flex-col items-center">
                            <span className="text-lg">{industry.icon}</span>
                            <span className="text-[10px] leading-tight">{industry.name.split('/')[0]}</span>
                          </div>
                        </th>
                      ))}
                    </tr>
                  </thead>
                  <tbody className="divide-y">
                    {REGULATIONS.map((reg) => (
                      <tr key={reg.code} className="hover:bg-slate-50">
                        <td className="px-2 py-2 font-medium sticky left-0 bg-white">
                          <span className="flex items-center gap-1">
                            {isInRag(reg.code) ? (
                              <span className="text-green-500 text-[10px]">●</span>
                            ) : (
                              <span className="text-red-300 text-[10px]">○</span>
                            )}
                            <span className="text-teal-600">{reg.code}</span>
                          </span>
                        </td>
                        {INDUSTRIES.filter(i => i.id !== 'all').map((industry) => {
                          const applies = INDUSTRY_REGULATION_MAP[industry.id]?.includes(reg.code)
                          return (
                            <td key={industry.id} className="px-2 py-2 text-center">
                              {applies ? (
                                <span className="inline-flex items-center justify-center w-5 h-5 bg-teal-100 text-teal-600 rounded-full">✓</span>
                              ) : (
                                <span className="inline-flex items-center justify-center w-5 h-5 text-slate-300">–</span>
                              )}
                            </td>
                          )
                        })}
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>

            {/* Future Outlook Section */}
            <div className="bg-gradient-to-r from-indigo-50 to-purple-50 rounded-xl border border-indigo-200 p-6">
              <div className="flex items-center gap-3 mb-4">
                <span className="text-2xl">🔮</span>
                <div>
                  <h3 className="font-semibold text-slate-900">Zukunftsaussicht</h3>
                  <p className="text-sm text-slate-500">Geplante Aenderungen und neue Regulierungen</p>
                </div>
              </div>

              <div className="space-y-4">
                {FUTURE_OUTLOOK.map((item) => (
                  <div key={item.id} className="bg-white rounded-lg border border-slate-200 overflow-hidden">
                    <div className="px-4 py-3 flex items-center justify-between bg-slate-50 border-b">
                      <div className="flex items-center gap-3">
                        <span className={`px-2 py-1 text-xs font-medium rounded ${
                          item.status === 'proposed' ? 'bg-yellow-100 text-yellow-700' :
                          item.status === 'agreed' ? 'bg-green-100 text-green-700' :
                          item.status === 'withdrawn' ? 'bg-red-100 text-red-700' :
                          'bg-blue-100 text-blue-700'
                        }`}>
                          {item.statusLabel}
                        </span>
                        <h4 className="font-semibold text-slate-900">{item.name}</h4>
                      </div>
                      <span className="text-sm text-slate-500">Erwartet: {item.expectedDate}</span>
                    </div>
                    <div className="p-4">
                      <p className="text-sm text-slate-600 mb-3">{item.description}</p>
                      <div className="mb-3">
                        <p className="text-xs font-medium text-slate-500 uppercase mb-2">Wichtige Aenderungen:</p>
                        <ul className="text-sm text-slate-600 space-y-1">
                          {item.keyChanges.slice(0, 4).map((change, idx) => (
                            <li key={idx} className="flex items-start gap-2">
                              <span className="text-teal-500 mt-1">•</span>
                              <span>{change}</span>
                            </li>
                          ))}
                          {item.keyChanges.length > 4 && (
                            <li className="text-slate-400 text-xs">+ {item.keyChanges.length - 4} weitere...</li>
                          )}
                        </ul>
                      </div>
                      <div className="flex items-center justify-between">
                        <div className="flex flex-wrap gap-1">
                          {item.affectedRegulations.map((code) => (
                            <span key={code} className="px-2 py-0.5 text-xs bg-slate-100 text-slate-600 rounded">
                              {code}
                            </span>
                          ))}
                        </div>
                        <a
                          href={item.source}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="text-xs text-teal-600 hover:underline"
                        >
                          Quelle →
                        </a>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {/* RAG Coverage Overview */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <div className="flex items-center gap-3 mb-4">
                <span className="text-2xl">✅</span>
                <div>
                  <h3 className="font-semibold text-slate-900">RAG-Abdeckung ({Object.keys(REGULATIONS_IN_RAG).length} von {REGULATIONS.length} Regulierungen)</h3>
                  <p className="text-sm text-slate-500">Stand: Februar 2026 — Alle im RAG-System verfuegbaren Regulierungen</p>
                </div>
              </div>

              <div className="flex flex-wrap gap-2">
                {REGULATIONS.filter(r => isInRag(r.code)).map((reg) => (
                  <span key={reg.code} className="px-2.5 py-1 text-xs font-medium bg-green-100 text-green-700 rounded-full border border-green-200">
                    ✓ {reg.code}
                  </span>
                ))}
              </div>
              <div className="mt-4 pt-4 border-t border-slate-100">
                <p className="text-xs font-medium text-slate-500 mb-2">Noch nicht im RAG:</p>
                <div className="flex flex-wrap gap-2">
                  {REGULATIONS.filter(r => !isInRag(r.code)).map((reg) => (
                    <span key={reg.code} className="px-2.5 py-1 text-xs font-medium bg-red-50 text-red-400 rounded-full border border-red-100">
                      ✗ {reg.code}
                    </span>
                  ))}
                </div>
              </div>
            </div>

            {/* Potential Future Regulations */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <div className="flex items-center gap-3 mb-4">
                <span className="text-2xl">🔮</span>
                <div>
                  <h3 className="font-semibold text-slate-900">Zukuenftige Regulierungen</h3>
                  <p className="text-sm text-slate-500">Noch nicht verabschiedet oder zur Erweiterung vorgesehen</p>
                </div>
              </div>

              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                {ADDITIONAL_REGULATIONS.map((reg) => (
                  <div key={reg.code} className={`rounded-lg border p-4 ${
                    reg.status === 'active' ? 'border-green-200 bg-green-50' : 'border-yellow-200 bg-yellow-50'
                  }`}>
                    <div className="flex items-center justify-between mb-2">
                      <div className="flex items-center gap-2">
                        <span className={`px-2 py-0.5 text-xs font-bold rounded ${
                          reg.type === 'eu_regulation' ? 'bg-blue-100 text-blue-700' : 'bg-purple-100 text-purple-700'
                        }`}>
                          {reg.code}
                        </span>
                        <span className={`px-2 py-0.5 text-xs rounded ${
                          reg.status === 'active' ? 'bg-green-100 text-green-700' : 'bg-yellow-100 text-yellow-700'
                        }`}>
                          {reg.status === 'active' ? 'In Kraft' : 'Vorgeschlagen'}
                        </span>
                      </div>
                      <span className={`px-2 py-0.5 text-xs rounded ${
                        reg.priority === 'high' ? 'bg-red-100 text-red-700' : 'bg-slate-100 text-slate-600'
                      }`}>
                        {reg.priority === 'high' ? 'Hohe Prioritaet' : 'Mittel'}
                      </span>
                    </div>
                    <h4 className="font-medium text-slate-900 text-sm mb-1">{reg.name}</h4>
                    <p className="text-xs text-slate-600 mb-2">{reg.description}</p>
                    <div className="flex items-center justify-between text-xs">
                      <span className="text-slate-500">Ab: {reg.effectiveDate}</span>
                      {reg.celex && (
                        <a
                          href={`https://eur-lex.europa.eu/legal-content/DE/TXT/?uri=CELEX:${reg.celex}`}
                          target="_blank"
                          rel="noopener noreferrer"
                          className="text-teal-600 hover:underline"
                        >
                          EUR-Lex →
                        </a>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </div>

            {/* Legal Basis Info */}
            <div className="bg-emerald-50 rounded-xl border border-emerald-200 p-6">
              <div className="flex items-center gap-3 mb-4">
                <span className="text-2xl">⚖️</span>
                <div>
                  <h3 className="font-semibold text-slate-900">{LEGAL_BASIS_INFO.title}</h3>
                  <p className="text-sm text-emerald-700">{LEGAL_BASIS_INFO.summary}</p>
                </div>
              </div>

              <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                {LEGAL_BASIS_INFO.details.map((detail, idx) => (
                  <div key={idx} className="bg-white rounded-lg border border-emerald-100 p-3">
                    <div className="flex items-center gap-2 mb-1">
                      <span className={`px-2 py-0.5 text-xs font-medium rounded ${
                        detail.status === 'Erlaubt' ? 'bg-green-100 text-green-700' : 'bg-yellow-100 text-yellow-700'
                      }`}>
                        {detail.status}
                      </span>
                      <span className="font-medium text-sm text-slate-900">{detail.aspect}</span>
                    </div>
                    <p className="text-xs text-slate-600">{detail.explanation}</p>
                  </div>
                ))}
              </div>
            </div>
          </div>
        )}

        {activeTab === 'search' && (
          <div className="space-y-6">
            {/* Search Box */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">Semantische Suche</h3>
              <div className="space-y-4">
                <div>
                  <label className="block text-sm font-medium text-slate-700 mb-2">Suchanfrage</label>
                  <textarea
                    value={searchQuery}
                    onChange={(e) => setSearchQuery(e.target.value)}
                    placeholder="z.B. 'Welche Anforderungen gibt es fuer KI-Systeme mit hohem Risiko?'"
                    rows={3}
                    className="w-full px-3 py-2 border rounded-lg focus:ring-2 focus:ring-teal-500 focus:border-teal-500"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-slate-700 mb-2">Filter (optional)</label>
                  <div className="flex flex-wrap gap-2">
                    {['GDPR', 'AIACT', 'CRA', 'NIS2', 'BSI-TR-03161-1'].map((code) => (
                      <button
                        key={code}
                        onClick={() => {
                          setSelectedRegulations((prev) =>
                            prev.includes(code) ? prev.filter((c) => c !== code) : [...prev, code]
                          )
                        }}
                        className={`px-3 py-1 text-sm rounded-full border transition-colors ${
                          selectedRegulations.includes(code)
                            ? 'bg-teal-100 border-teal-300 text-teal-700'
                            : 'bg-white border-slate-200 text-slate-600 hover:border-slate-300'
                        }`}
                      >
                        {code}
                      </button>
                    ))}
                  </div>
                </div>
                <button
                  onClick={handleSearch}
                  disabled={searching || !searchQuery.trim()}
                  className="px-6 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 disabled:opacity-50"
                >
                  {searching ? 'Suche...' : 'Suchen'}
                </button>
              </div>
            </div>

            {/* Search Results */}
            {searchResults.length > 0 && (
              <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
                <div className="px-4 py-3 border-b bg-slate-50">
                  <h3 className="font-semibold text-slate-900">{searchResults.length} Ergebnisse</h3>
                </div>
                <div className="divide-y">
                  {searchResults.map((result, i) => (
                    <div key={i} className="p-4">
                      <div className="flex items-center gap-2 mb-2">
                        <span className="px-2 py-0.5 text-xs rounded bg-teal-100 text-teal-700">
                          {result.regulation_code}
                        </span>
                        {result.article && (
                          <span className="text-sm text-slate-500">Art. {result.article}</span>
                        )}
                        <span className="ml-auto text-sm text-slate-400">
                          Score: {(result.score * 100).toFixed(1)}%
                        </span>
                      </div>
                      <p className="text-slate-700 text-sm">{result.text}</p>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        )}

        {activeTab === 'chunks' && (
          <ChunkBrowserQA apiProxy={API_PROXY} />
        )}

        {activeTab === 'data' && (
          <div className="space-y-6">
            {/* Upload Document */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">Dokument hochladen (PDF)</h3>
              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                <div>
                  <label className="block text-sm font-medium text-slate-700 mb-2">PDF-Datei</label>
                  <input
                    type="file"
                    accept=".pdf"
                    onChange={(e) => setUploadFile(e.target.files?.[0] || null)}
                    className="w-full px-3 py-2 border rounded-lg text-sm"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-slate-700 mb-2">Titel</label>
                  <input
                    type="text"
                    value={uploadTitle}
                    onChange={(e) => setUploadTitle(e.target.value)}
                    placeholder="z.B. Firmen-Datenschutzrichtlinie"
                    className="w-full px-3 py-2 border rounded-lg"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-slate-700 mb-2">Code (eindeutig)</label>
                  <input
                    type="text"
                    value={uploadCode}
                    onChange={(e) => setUploadCode(e.target.value.toUpperCase())}
                    placeholder="z.B. CUSTOM-DSR-01"
                    className="w-full px-3 py-2 border rounded-lg font-mono"
                  />
                </div>
              </div>
              <button
                onClick={handleUpload}
                disabled={uploading || !uploadFile || !uploadTitle || !uploadCode}
                className="mt-4 px-6 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 disabled:opacity-50"
              >
                {uploading ? 'Wird hochgeladen...' : 'Hochladen & Indexieren'}
              </button>
            </div>

            {/* Add Link */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">Link hinzufuegen (Webseite/PDF)</h3>
              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
                <div>
                  <label className="block text-sm font-medium text-slate-700 mb-2">URL</label>
                  <input
                    type="url"
                    value={linkUrl}
                    onChange={(e) => setLinkUrl(e.target.value)}
                    placeholder="https://example.com/document.pdf"
                    className="w-full px-3 py-2 border rounded-lg"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-slate-700 mb-2">Titel</label>
                  <input
                    type="text"
                    value={linkTitle}
                    onChange={(e) => setLinkTitle(e.target.value)}
                    placeholder="z.B. BSI IT-Grundschutz"
                    className="w-full px-3 py-2 border rounded-lg"
                  />
                </div>
                <div>
                  <label className="block text-sm font-medium text-slate-700 mb-2">Code (eindeutig)</label>
                  <input
                    type="text"
                    value={linkCode}
                    onChange={(e) => setLinkCode(e.target.value.toUpperCase())}
                    placeholder="z.B. BSI-GRUNDSCHUTZ"
                    className="w-full px-3 py-2 border rounded-lg font-mono"
                  />
                </div>
              </div>
              <button
                onClick={handleAddLink}
                disabled={addingLink || !linkUrl || !linkTitle || !linkCode}
                className="mt-4 px-6 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 disabled:opacity-50"
              >
                {addingLink ? 'Wird hinzugefuegt...' : 'Link hinzufuegen & Indexieren'}
              </button>
            </div>

            {/* Custom Documents List */}
            <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
              <div className="px-4 py-3 border-b bg-slate-50 flex items-center justify-between">
                <h3 className="font-semibold text-slate-900">Eigene Dokumente ({customDocuments.length})</h3>
                <button
                  onClick={fetchCustomDocuments}
                  className="text-sm text-teal-600 hover:text-teal-700"
                >
                  Aktualisieren
                </button>
              </div>
              {customDocuments.length === 0 ? (
                <div className="p-8 text-center text-slate-500">
                  Noch keine eigenen Dokumente hinzugefuegt.
                </div>
              ) : (
                <div className="divide-y">
                  {customDocuments.map((doc) => (
                    <div key={doc.id} className="px-4 py-3 flex items-center justify-between">
                      <div className="flex items-center gap-3">
                        <span className="w-8 h-8 rounded-lg bg-slate-100 flex items-center justify-center text-lg">
                          {doc.url ? '🔗' : '📄'}
                        </span>
                        <div>
                          <p className="font-medium text-slate-900">{doc.title}</p>
                          <p className="text-sm text-slate-500">
                            <span className="font-mono text-teal-600">{doc.code}</span>
                            {' • '}
                            {doc.filename || doc.url}
                          </p>
                        </div>
                      </div>
                      <div className="flex items-center gap-4">
                        <span className={`px-2 py-1 rounded text-xs font-medium ${
                          doc.status === 'indexed' ? 'bg-green-100 text-green-700' :
                          doc.status === 'error' ? 'bg-red-100 text-red-700' :
                          doc.status === 'processing' || doc.status === 'fetching' ? 'bg-blue-100 text-blue-700' :
                          'bg-slate-100 text-slate-700'
                        }`}>
                          {doc.status === 'indexed' ? `${doc.chunk_count} Chunks` :
                           doc.status === 'error' ? 'Fehler' :
                           doc.status === 'processing' ? 'Verarbeitung...' :
                           doc.status === 'fetching' ? 'Abruf...' :
                           doc.status}
                        </span>
                        <button
                          onClick={() => handleDeleteDocument(doc.id)}
                          className="text-red-500 hover:text-red-700 text-sm"
                        >
                          Loeschen
                        </button>
                      </div>
                    </div>
                  ))}
                </div>
              )}
            </div>

            {/* Info Box */}
            <div className="bg-teal-50 border border-teal-200 rounded-xl p-6">
              <h4 className="font-semibold text-teal-800 flex items-center gap-2">
                <span>ℹ️</span>
                Hinweis zur Verwendung
              </h4>
              <p className="text-sm text-teal-700 mt-2">
                Laden Sie eigene Dokumente (z.B. interne Datenschutzrichtlinien, Vertraege) oder
                externe Links hoch. Diese werden automatisch in Chunks aufgeteilt und indexiert.
                Nach dem Hinzufuegen koennen Sie im <strong>Pipeline</strong>-Tab die vollstaendige
                Compliance-Analyse starten.
              </p>
            </div>
          </div>
        )}

        {activeTab === 'ingestion' && (
          <div className="space-y-6">
            {/* Ingestion Control */}
            <div className="bg-white rounded-xl border border-slate-200 p-6">
              <h3 className="font-semibold text-slate-900 mb-4">Legal Corpus Re-Ingestion</h3>
              <p className="text-slate-600 mb-4">
                Startet die Neuindexierung aller 19 Regulierungen. Die Dokumente werden von EUR-Lex,
                gesetze-im-internet.de und BSI heruntergeladen, in semantische Chunks aufgeteilt und
                mit BGE-M3 Embeddings in Qdrant indexiert.
              </p>
              <div className="flex items-center gap-4">
                <button
                  onClick={triggerIngestion}
                  disabled={ingestionRunning}
                  className="px-6 py-2 bg-teal-600 text-white rounded-lg hover:bg-teal-700 disabled:opacity-50"
                >
                  {ingestionRunning ? 'Laeuft...' : 'Re-Ingestion starten'}
                </button>
                {ingestionRunning && (
                  <span className="flex items-center gap-2 text-teal-600">
                    <svg className="animate-spin h-4 w-4" fill="none" viewBox="0 0 24 24">
                      <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                      <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.7.689 3 7.938l3-2.647z" />
                    </svg>
                    Ingestion laeuft...
                  </span>
                )}
              </div>
            </div>

            {/* Ingestion Log */}
            {ingestionLog.length > 0 && (
              <div className="bg-slate-900 rounded-xl p-4">
                <h4 className="text-slate-400 text-sm mb-2">Log</h4>
                <div className="font-mono text-sm text-green-400 space-y-1 max-h-64 overflow-y-auto">
                  {ingestionLog.map((line, i) => (
                    <div key={i}>{line}</div>
                  ))}
                </div>
              </div>
            )}

            {/* Info Box */}
            <div className="bg-teal-50 border border-teal-200 rounded-xl p-6">
              <h4 className="font-semibold text-teal-800 flex items-center gap-2">
                <span>💡</span>
                Hinweis zur Datenquelle
              </h4>
              <p className="text-sm text-teal-700 mt-2">
                Alle indexierten Dokumente sind amtliche Werke (§5 UrhG) und damit urheberrechtsfrei.
                Sie werden nur fuer RAG/Retrieval verwendet, nicht fuer Modell-Training.
                Die Daten werden lokal auf dem Mac Mini verarbeitet und nicht an externe Dienste gesendet.
              </p>
            </div>
          </div>
        )}

        {activeTab === 'pipeline' && (
          <div className="space-y-6">
            {/* Pipeline Header */}
            <div className="flex items-center justify-between flex-wrap gap-4">
              <div className="flex items-center gap-4">
                <h3 className="text-lg font-semibold text-slate-900">Compliance Pipeline Status</h3>
                {/* Running Time Indicator */}
                {pipelineState?.status === 'running' && elapsedTime && (
                  <div className="flex items-center gap-2 px-3 py-1.5 bg-blue-50 border border-blue-200 rounded-full">
                    <div className="w-2 h-2 bg-blue-500 rounded-full animate-pulse" />
                    <span className="text-sm font-medium text-blue-700">Laufzeit: {elapsedTime}</span>
                  </div>
                )}
              </div>
              <div className="flex items-center gap-3">
                {/* Auto-Refresh Toggle */}
                <label className="flex items-center gap-2 text-sm text-slate-600 cursor-pointer">
                  <input
                    type="checkbox"
                    checked={autoRefresh}
                    onChange={(e) => setAutoRefresh(e.target.checked)}
                    className="w-4 h-4 text-teal-600 rounded border-slate-300 focus:ring-teal-500"
                  />
                  Auto-Refresh
                </label>
                {/* Start Pipeline Button */}
                {(!pipelineState || pipelineState.status !== 'running') && (
                  <button
                    onClick={() => handleStartPipeline(false)}
                    disabled={pipelineStarting}
                    className="flex items-center gap-2 px-4 py-2 text-sm bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50"
                  >
                    {pipelineStarting ? (
                      <svg className="animate-spin h-4 w-4" fill="none" viewBox="0 0 24 24">
                        <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                        <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.7.689 3 7.938l3-2.647z" />
                      </svg>
                    ) : (
                      <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                      </svg>
                    )}
                    Pipeline starten
                  </button>
                )}
                <button
                  onClick={fetchPipeline}
                  disabled={pipelineLoading}
                  className="flex items-center gap-2 px-4 py-2 text-sm bg-teal-600 text-white rounded-lg hover:bg-teal-700 disabled:opacity-50"
                >
                  {pipelineLoading ? (
                    <svg className="animate-spin h-4 w-4" fill="none" viewBox="0 0 24 24">
                      <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                      <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.7.689 3 7.938l3-2.647z" />
                    </svg>
                  ) : (
                    <svg className="w-4 h-4" 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>
                  )}
                  Aktualisieren
                </button>
              </div>
            </div>

            {/* No Data */}
            {(!pipelineState || pipelineState.status === 'no_data') && !pipelineLoading && (
              <div className="bg-white rounded-xl border border-slate-200 p-8 text-center">
                <div className="w-16 h-16 mx-auto mb-4 rounded-full bg-slate-100 flex items-center justify-center">
                  <svg className="w-8 h-8 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>
                <h4 className="text-lg font-semibold text-slate-900 mb-2">Keine Pipeline-Daten</h4>
                <p className="text-slate-600 mb-4">
                  Es wurde noch keine Pipeline ausgefuehrt. Starten Sie die Compliance-Pipeline um Checkpoint-Daten zu sehen.
                </p>
                <button
                  onClick={() => handleStartPipeline(false)}
                  disabled={pipelineStarting}
                  className="inline-flex items-center gap-2 px-6 py-3 bg-green-600 text-white rounded-lg hover:bg-green-700 disabled:opacity-50"
                >
                  {pipelineStarting ? (
                    <>
                      <svg className="animate-spin h-5 w-5" fill="none" viewBox="0 0 24 24">
                        <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                        <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.7.689 3 7.938l3-2.647z" />
                      </svg>
                      Startet...
                    </>
                  ) : (
                    <>
                      <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
                        <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
                      </svg>
                      Pipeline jetzt starten
                    </>
                  )}
                </button>
              </div>
            )}

            {/* Pipeline Status */}
            {pipelineState && pipelineState.status !== 'no_data' && (
              <>
                {/* Status Card */}
                <div className="bg-white rounded-xl border border-slate-200 p-6">
                  <div className="flex items-center justify-between">
                    <div className="flex items-center gap-4">
                      <div className={`w-12 h-12 rounded-xl flex items-center justify-center ${
                        pipelineState.status === 'completed' ? 'bg-green-100' :
                        pipelineState.status === 'running' ? 'bg-blue-100' :
                        pipelineState.status === 'failed' ? 'bg-red-100' : 'bg-slate-100'
                      }`}>
                        {pipelineState.status === 'completed' && (
                          <svg className="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                          </svg>
                        )}
                        {pipelineState.status === 'running' && (
                          <svg className="w-6 h-6 text-blue-600 animate-spin" fill="none" viewBox="0 0 24 24">
                            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.7.689 3 7.938l3-2.647z" />
                          </svg>
                        )}
                        {pipelineState.status === 'failed' && (
                          <svg className="w-6 h-6 text-red-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                          </svg>
                        )}
                      </div>
                      <div>
                        <h4 className="font-semibold text-slate-900">Pipeline {pipelineState.pipeline_id}</h4>
                        <p className="text-sm text-slate-500">
                          Gestartet: {pipelineState.started_at ? new Date(pipelineState.started_at).toLocaleString('de-DE') : '-'}
                          {pipelineState.completed_at && ` | Beendet: ${new Date(pipelineState.completed_at).toLocaleString('de-DE')}`}
                        </p>
                      </div>
                    </div>
                    <span className={`px-3 py-1 rounded-full text-sm font-medium ${
                      pipelineState.status === 'completed' ? 'bg-green-100 text-green-700' :
                      pipelineState.status === 'running' ? 'bg-blue-100 text-blue-700' :
                      pipelineState.status === 'failed' ? 'bg-red-100 text-red-700' : 'bg-slate-100 text-slate-700'
                    }`}>
                      {pipelineState.status === 'completed' ? 'Abgeschlossen' :
                       pipelineState.status === 'running' ? 'Laeuft' :
                       pipelineState.status === 'failed' ? 'Fehlgeschlagen' : pipelineState.status}
                    </span>
                  </div>
                </div>

                {/* Current Progress - only when running */}
                {pipelineState.status === 'running' && pipelineState.current_phase && (
                  <div className="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl border border-blue-200 p-6">
                    <div className="flex items-center justify-between mb-4">
                      <h4 className="font-semibold text-blue-900 flex items-center gap-2">
                        <svg className="w-5 h-5 animate-pulse" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                          <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 10V3L4 14h7v7l9-11h-7z" />
                        </svg>
                        Aktuelle Verarbeitung
                      </h4>
                      <span className="text-sm text-blue-600">Phase: {pipelineState.current_phase}</span>
                    </div>

                    {/* Phase Progress Indicator */}
                    <div className="flex items-center gap-2 mb-4">
                      {['ingestion', 'extraction', 'controls', 'measures'].map((phase, idx) => (
                        <div key={phase} className="flex-1 flex items-center">
                          <div className={`flex-1 h-2 rounded-full ${
                            pipelineState.current_phase === phase ? 'bg-blue-500 animate-pulse' :
                            pipelineState.checkpoints?.some((c: PipelineCheckpoint) => c.phase === phase && c.status === 'completed') ? 'bg-green-500' :
                            'bg-slate-200'
                          }`} />
                          {idx < 3 && <div className="w-2" />}
                        </div>
                      ))}
                    </div>
                    <div className="flex justify-between text-xs text-slate-500 mb-4">
                      <span>Ingestion</span>
                      <span>Extraktion</span>
                      <span>Controls</span>
                      <span>Massnahmen</span>
                    </div>

                    {/* Current checkpoint details */}
                    {pipelineState.checkpoints?.filter((c: PipelineCheckpoint) => c.status === 'running').map((checkpoint: PipelineCheckpoint, idx: number) => (
                      <div key={idx} className="bg-white/60 rounded-lg p-4 mt-2">
                        <div className="flex items-center justify-between">
                          <div className="flex items-center gap-3">
                            <div className="w-3 h-3 bg-blue-500 rounded-full animate-pulse" />
                            <span className="font-medium text-slate-900">{checkpoint.name}</span>
                          </div>
                          {checkpoint.metrics && Object.keys(checkpoint.metrics).length > 0 && (
                            <div className="flex gap-2">
                              {Object.entries(checkpoint.metrics).slice(0, 3).map(([key, value]) => (
                                <span key={key} className="px-2 py-1 bg-blue-100 text-blue-700 rounded text-xs">
                                  {key.replace(/_/g, ' ')}: {typeof value === 'number' ? value.toLocaleString() : String(value)}
                                </span>
                              ))}
                            </div>
                          )}
                        </div>
                      </div>
                    ))}

                    {/* Live chunk count */}
                    <div className="mt-4 flex items-center justify-between text-sm">
                      <span className="text-slate-600">Chunks in Qdrant:</span>
                      <span className="font-bold text-blue-700">{collectionStatus?.totalPoints?.toLocaleString() || '-'}</span>
                    </div>
                  </div>
                )}

                {/* Validation Summary */}
                {pipelineState.validation_summary && (
                  <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                    <div className="bg-white rounded-xl border border-green-200 p-4">
                      <p className="text-sm text-slate-500">Bestanden</p>
                      <p className="text-2xl font-bold text-green-600">{pipelineState.validation_summary.passed}</p>
                    </div>
                    <div className="bg-white rounded-xl border border-yellow-200 p-4">
                      <p className="text-sm text-slate-500">Warnungen</p>
                      <p className="text-2xl font-bold text-yellow-600">{pipelineState.validation_summary.warning}</p>
                    </div>
                    <div className="bg-white rounded-xl border border-red-200 p-4">
                      <p className="text-sm text-slate-500">Fehlgeschlagen</p>
                      <p className="text-2xl font-bold text-red-600">{pipelineState.validation_summary.failed}</p>
                    </div>
                    <div className="bg-white rounded-xl border border-slate-200 p-4">
                      <p className="text-sm text-slate-500">Gesamt</p>
                      <p className="text-2xl font-bold text-slate-700">{pipelineState.validation_summary.total}</p>
                    </div>
                  </div>
                )}

                {/* Checkpoints */}
                <div className="bg-white rounded-xl border border-slate-200 overflow-hidden">
                  <div className="px-4 py-3 border-b bg-slate-50">
                    <h3 className="font-semibold text-slate-900">Checkpoints ({pipelineState.checkpoints?.length || 0})</h3>
                  </div>
                  <div className="divide-y">
                    {pipelineState.checkpoints?.map((checkpoint, idx) => (
                      <div key={idx} className="p-4">
                        <div className="flex items-center justify-between mb-2">
                          <div className="flex items-center gap-3">
                            <span className={`w-3 h-3 rounded-full ${
                              checkpoint.phase === 'ingestion' ? 'bg-blue-500' :
                              checkpoint.phase === 'extraction' ? 'bg-purple-500' :
                              checkpoint.phase === 'controls' ? 'bg-green-500' : 'bg-orange-500'
                            }`} />
                            <span className="font-medium text-slate-900">{checkpoint.name}</span>
                            <span className="text-sm text-slate-500">
                              ({checkpoint.phase}) |
                              {checkpoint.duration_seconds ? ` ${checkpoint.duration_seconds.toFixed(1)}s` : ' -'}
                            </span>
                          </div>
                          <span className={`px-2 py-0.5 rounded text-xs font-medium ${
                            checkpoint.status === 'completed' ? 'bg-green-100 text-green-700' :
                            checkpoint.status === 'running' ? 'bg-blue-100 text-blue-700' :
                            checkpoint.status === 'failed' ? 'bg-red-100 text-red-700' : 'bg-slate-100 text-slate-700'
                          }`}>
                            {checkpoint.status}
                          </span>
                        </div>

                        {/* Metrics */}
                        {Object.keys(checkpoint.metrics || {}).length > 0 && (
                          <div className="flex flex-wrap gap-2 mt-2">
                            {Object.entries(checkpoint.metrics).map(([key, value]) => (
                              <span key={key} className="px-2 py-1 bg-slate-100 rounded text-xs text-slate-600">
                                {key.replace(/_/g, ' ')}: <strong>{typeof value === 'number' ? value.toLocaleString() : String(value)}</strong>
                              </span>
                            ))}
                          </div>
                        )}

                        {/* Validations */}
                        {checkpoint.validations?.length > 0 && (
                          <div className="mt-3 space-y-1">
                            {checkpoint.validations.map((v, vIdx) => (
                              <div key={vIdx} className="flex items-center gap-2 text-sm">
                                <span className={`w-4 h-4 flex items-center justify-center ${
                                  v.status === 'passed' ? 'text-green-500' :
                                  v.status === 'warning' ? 'text-yellow-500' : 'text-red-500'
                                }`}>
                                  {v.status === 'passed' ? '✓' : v.status === 'warning' ? '⚠' : '✗'}
                                </span>
                                <span className="text-slate-700">{v.name}:</span>
                                <span className="text-slate-500">{v.message}</span>
                              </div>
                            ))}
                          </div>
                        )}

                        {/* Error */}
                        {checkpoint.error && (
                          <div className="mt-2 p-2 bg-red-50 border border-red-200 rounded text-sm text-red-700">
                            {checkpoint.error}
                          </div>
                        )}
                      </div>
                    ))}
                    {(!pipelineState.checkpoints || pipelineState.checkpoints.length === 0) && (
                      <div className="p-4 text-center text-slate-500">
                        Noch keine Checkpoints vorhanden.
                      </div>
                    )}
                  </div>
                </div>

                {/* Summary */}
                {Object.keys(pipelineState.summary || {}).length > 0 && (
                  <div className="bg-white rounded-xl border border-slate-200 p-4">
                    <h4 className="font-semibold text-slate-900 mb-3">Zusammenfassung</h4>
                    <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                      {Object.entries(pipelineState.summary).map(([key, value]) => (
                        <div key={key}>
                          <p className="text-sm text-slate-500">{key.replace(/_/g, ' ')}</p>
                          <p className="font-bold text-slate-900">
                            {typeof value === 'number' ? value.toLocaleString() : String(value)}
                          </p>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </>
            )}
          </div>
        )}
      </div>
    </div>
  )
}
