'use client'

// Erklärendes Architekturschema des Compliance-Check-Tools — Muster aus dem
// CE-Modul (/sdk/iace/.../architektur) übernommen: hand-kurierte Boxen/Pfeile +
// Schritt-Akkordeon. Inhalt spiegelt den Code-Pfad (api/agent_check/_orchestrator
// + services/specialist_agents). Bewusst statisch (der Doc-Check ist Python, hat
// keinen Architektur-Endpoint wie das Go-IACE-Modul) — bei Bedarf später aus einem
// Backend-Handler speisbar.

import { useState, type ReactNode } from 'react'

function Box({ title, sub, accent }: { title: string; sub?: string; accent?: 'purple' | 'amber' | 'green' | 'gray' }) {
  const c =
    accent === 'purple'
      ? 'border-purple-300 bg-purple-50/60 dark:border-purple-700 dark:bg-purple-900/20'
      : accent === 'amber'
        ? 'border-amber-300 bg-amber-50/60 dark:border-amber-700 dark:bg-amber-900/20'
        : accent === 'green'
          ? 'border-green-300 bg-green-50/60 dark:border-green-700 dark:bg-green-900/20'
          : 'border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800'
  return (
    <div className={`rounded-lg border ${c} px-2.5 py-1.5`}>
      <div className="text-[11px] font-medium text-gray-800 dark:text-gray-200 leading-tight">{title}</div>
      {sub && <div className="text-[10px] text-gray-500 leading-tight mt-0.5">{sub}</div>}
    </div>
  )
}

function Lane({ label, children }: { label: string; children: ReactNode }) {
  return (
    <div className="flex-1 min-w-[150px] space-y-2">
      <div className="text-[10px] font-semibold uppercase tracking-wide text-gray-400 text-center">{label}</div>
      <div className="space-y-1.5">{children}</div>
    </div>
  )
}

function Arrow() {
  return (
    <div className="flex items-center justify-center text-gray-300 dark:text-gray-600 shrink-0 px-0.5">
      <span className="hidden lg:block text-lg">→</span>
      <span className="lg:hidden text-sm">↓</span>
    </div>
  )
}

type Stage = {
  id: string
  title: string
  summary: string
  input: string
  logic: string
  source: string
  example: string
}

// Spiegelt run_compliance_check (Phasen A–F) + die Spezialagenten-Schicht.
const STAGES: Stage[] = [
  {
    id: 'a',
    title: 'Phase A — Auflösen & Crawl',
    summary: 'URLs + hochgeladene Dokumente einsammeln, fehlende Pflichtseiten automatisch finden.',
    input: 'Start-URL, Dokument-Uploads, 8 Wizard-Felder (scan_context)',
    logic: 'Discovery (Sitemap/Heuristik) + Fetch je Seite, Text-Extraktion pro Doc-Typ',
    source: 'consent-tester /dsi-discovery, Playwright',
    example: 'Findet /impressum, /datenschutz, /agb ohne manuelle Eingabe',
  },
  {
    id: 'b',
    title: 'Phase B — Profil & Dokument-Checks',
    summary: 'Geschäftsprofil erkennen, jedes Dokument gegen seine Controls prüfen.',
    input: 'Doc-Texte je Typ + Business-Scope',
    logic: 'Regex-Runner + MC-Keyword + BGE-M3-Embedding + LLM-Verify (nur unscharf)',
    source: 'doc_check_controls (DB), mc_classification.db (Embeddings)',
    example: 'DSE: 267 Text-MCs, Keyword + semantischer Recall',
  },
  {
    id: 'agents',
    title: 'Spezialagenten (nebenläufig)',
    summary: 'Pro Dokumenttyp ein typisierter Agent → eigener Ergebnis-Tab, gefüllt per SSE.',
    input: 'Doc-Text, Scope, scan_context',
    logic: 'Impressum + AGB + DSE laufen parallel (asyncio.gather), je ein AgentOutput',
    source: 'api/agent_check/_agent_outputs._TOPIC_AGENTS',
    example: 'AGB-Tab + DSE-Tab erscheinen, sobald ihr Agent fertig ist',
  },
  {
    id: 'c',
    title: 'Phase C — Cookie-Banner',
    summary: 'Consent-Banner + gesetzte Cookies vor/nach Einwilligung live prüfen.',
    input: 'Live-Seite im Browser',
    logic: 'Consent-Tester-Scan: Banner, Vendors, Enforcement, Browser-Matrix',
    source: 'consent-tester /scan',
    example: 'Cookie vor Einwilligung gesetzt → Verstoß-Kandidat',
  },
  {
    id: 'd',
    title: 'Phase D — Vendors & Plausibilität',
    summary: 'Dritt-Dienste extrahieren + Findings auf Plausibilität prüfen.',
    input: 'Banner-/Seiten-Daten, Findings',
    logic: 'Vendor-Extraktion (+OCR-Fallback), Plausibilitäts-Check je FAIL',
    source: 'Cookie-/Vendor-Kataloge, LLM-Kaskade',
    example: 'Analytics ohne Rechtsgrundlage → bestätigtes Finding',
  },
  {
    id: 'reconcile',
    title: 'Cross-Finding-Abgleich',
    summary: 'Findings über Dokumente hinweg abgleichen — Doppel & Scheinverstöße auflösen.',
    input: 'Alle Modul-Findings',
    logic: 'Deckt ein anderes Dokument die Pflicht ab, wird das Cross-Finding unterdrückt',
    source: 'cross_doc_reconcile (B-Wirings)',
    example: '§36 VSBG im Impressum statt DSE → kein Doppel-Finding',
  },
  {
    id: 'f',
    title: 'Phase E/F — Bericht & Snapshot',
    summary: 'Ergebnis persistieren, Snapshot für die Historie speichern.',
    input: 'Konsolidiertes Ergebnis',
    logic: 'Mail-Render + DB-Persist + Snapshot (Tab-Ansicht ohne Re-Crawl)',
    source: 'compliance_check_snapshots',
    example: 'Historie erneut öffnen, ohne die Seite neu zu crawlen',
  },
]

type ModuleEngine = { name: string; mechanism: string }
const MODULES: ModuleEngine[] = [
  { name: 'Impressum', mechanism: 'Scope-Gate + Feld-Matcher (§5 DDG / §18 MStV)' },
  { name: 'AGB', mechanism: 'decision_method-Routing: Keyword → Geschäftsmodell-Gate → Embedding/Reference/LLM' },
  { name: 'DSE', mechanism: '4-Layer: Regex-Boost → Keyword → BGE-M3-Recall (0.65) → Semantic-Validator' },
  { name: 'Cookie-Banner', mechanism: 'Consent-Tester: Banner, Vendors, Enforcement, Browser-Matrix' },
]

type Pruefer = { method: string; mechanism: string; deterministic: string; example: string }
// Meta-Modell: jede Pflicht → ein Prüfertyp (decision_method). Wenige
// wiederverwendbare Prüfer statt Logik pro Control.
const PRUEFER: Pruefer[] = [
  { method: 'REGEX', mechanism: 'Kuratierte Muster / Keyword', deterministic: 'ja', example: 'Pflicht-Stichwort im Text' },
  { method: 'EMBEDDING', mechanism: 'BGE-M3 Kosinus ≥ Schwelle', deterministic: 'ja (feste Funktion)', example: '„Recht auf Berichtigung" ≈ Umschreibung' },
  { method: 'REFERENCE', mechanism: 'Link-/Verweis-Auflösung', deterministic: 'ja', example: 'Verweis auf die Datenschutzerklärung' },
  { method: 'LLM', mechanism: 'Kaskade Qwen→OVH→Claude, nur unscharfe Fälle', deterministic: 'nein (eskaliert)', example: 'Speicherdauer inhaltlich erfüllt?' },
  { method: 'BEHAVIOR', mechanism: 'Playwright: Live-Verhalten', deterministic: 'ja', example: 'Cookies vor Einwilligung gesetzt?' },
  { method: 'SCANNER', mechanism: 'Repo-/Netzwerk-/Prozess-Scan', deterministic: 'ja', example: 'Geplant: technische Nachweise' },
]

function Field({ label, value, mono }: { label: string; value: string; mono?: boolean }) {
  return (
    <div>
      <dt className="text-[10px] uppercase tracking-wide text-gray-400">{label}</dt>
      <dd className={`text-gray-600 dark:text-gray-300 ${mono ? 'font-mono text-[11px]' : ''}`}>{value}</dd>
    </div>
  )
}

function StageRow({ stage, last, open, onToggle }: { stage: Stage; last: boolean; open: boolean; onToggle: () => void }) {
  return (
    <div>
      <button
        onClick={onToggle}
        className={`w-full text-left rounded-lg border p-3 transition-colors ${
          open
            ? 'border-purple-300 bg-purple-50/60 dark:border-purple-700 dark:bg-purple-900/20'
            : 'border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700/50'
        }`}
      >
        <div className="flex items-start justify-between gap-3">
          <div>
            <div className="text-sm font-semibold text-gray-800 dark:text-gray-200">{stage.title}</div>
            <div className="text-xs text-gray-500 mt-0.5">{stage.summary}</div>
          </div>
          <span className="text-gray-400 text-xs shrink-0">{open ? '▲' : '▼'}</span>
        </div>
        {open && (
          <dl className="mt-3 grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-2 text-xs">
            <Field label="Input" value={stage.input} />
            <Field label="Logik" value={stage.logic} />
            <Field label="Datenquelle" value={stage.source} mono />
            <Field label="Beispiel" value={stage.example} />
          </dl>
        )}
      </button>
      {!last && <div className="flex justify-center text-gray-300 dark:text-gray-600 text-xs leading-none py-0.5">↓</div>}
    </div>
  )
}

export function ArchitekturView() {
  const [open, setOpen] = useState<string | null>('b')

  return (
    <div className="space-y-8">
      <div>
        <h2 className="text-xl font-bold text-gray-900 dark:text-gray-100">Architektur &amp; Datenfluss</h2>
        <p className="text-sm text-gray-500 dark:text-gray-400 max-w-3xl mt-1">
          Nachvollziehbar: <strong>woher jedes Finding stammt</strong> und <strong>wie es geprüft wird</strong>.
          Die Engine ist überwiegend <strong>deterministisch</strong> (Regex + Embedding); ein LLM entscheidet nur
          die unscharfen Fälle. Ergebnisse erscheinen pro Modul progressiv und werden am Ende per
          Cross-Finding-Abgleich bereinigt.
        </p>
      </div>

      <section className="space-y-2">
        <h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300">Datenfluss (Überblick)</h3>
        <div className="rounded-xl border border-gray-200 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-900/20 p-3 overflow-x-auto">
          <div className="flex flex-col lg:flex-row gap-1.5 lg:items-stretch min-w-[280px]">
            <Lane label="Eingabe">
              <Box title="Website + Dokumente" sub="Impressum · DSE · AGB · Cookies" accent="purple" />
              <Box title="Wizard-Kontext" sub="8 Felder: Shop, Drittland, Beruf…" accent="purple" />
            </Lane>
            <Arrow />
            <Lane label="Crawl + Text">
              <Box title="Discovery + Fetch" sub="consent-tester, Playwright" />
              <Box title="Doc-Text je Typ" />
            </Lane>
            <Arrow />
            <Lane label="Engine (deterministisch)">
              <div className="rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-1.5 space-y-1">
                {STAGES.map((s) => (
                  <div key={s.id} className="text-[10px] text-gray-600 dark:text-gray-300 leading-tight">
                    {s.title}
                  </div>
                ))}
              </div>
            </Lane>
            <Arrow />
            <Lane label="Ausgaben">
              <Box title="Findings je Modul-Tab" sub="Impressum/AGB/DSE/Cookie" accent="green" />
              <Box title="Severity + Maßnahme" accent="green" />
              <Box title="Snapshot + Bericht" sub="ohne Re-Crawl" accent="green" />
            </Lane>
          </div>
          <p className="text-[10px] text-gray-400 mt-2">
            Links→rechts reproduzierbar. Embedding ist semantisch UND deterministisch (feste Funktion: gleicher
            Text → gleicher Vektor). Das LLM läuft nur für unscharfe Fälle und eskaliert mit Selbstkonfidenz.
          </p>
        </div>
      </section>

      <section className="space-y-2">
        <h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300">Pipeline (Schritt für Schritt)</h3>
        <div className="space-y-1">
          {STAGES.map((s, i) => (
            <StageRow
              key={s.id}
              stage={s}
              last={i === STAGES.length - 1}
              open={open === s.id}
              onToggle={() => setOpen(open === s.id ? null : s.id)}
            />
          ))}
        </div>
      </section>

      <section className="space-y-3">
        <h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300">Modul-Engines (live)</h3>
        <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
          {MODULES.map((m) => (
            <div key={m.name} className="rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 p-3">
              <div className="flex items-baseline justify-between gap-2">
                <span className="text-sm font-medium text-gray-800 dark:text-gray-200">{m.name}</span>
                <span className="inline-block rounded px-1.5 py-0.5 text-[10px] font-medium bg-green-100 text-green-700 dark:bg-green-900/40 dark:text-green-300">
                  live
                </span>
              </div>
              <p className="text-xs text-gray-500 mt-1">{m.mechanism}</p>
            </div>
          ))}
        </div>
      </section>

      <section className="space-y-3">
        <h3 className="text-sm font-semibold text-gray-700 dark:text-gray-300">Prüfer-Matrix (Meta-Modell)</h3>
        <p className="text-xs text-gray-500 max-w-3xl">
          Jede Pflicht wird einem <strong>Prüfertyp</strong> zugeordnet — so braucht es nicht pro Control eigene
          Logik, sondern wenige wiederverwendbare Prüfer.
        </p>
        <div className="overflow-x-auto">
          <table className="w-full text-xs">
            <thead>
              <tr className="text-gray-500 border-b border-gray-200 dark:border-gray-700 text-left">
                <th className="py-1.5 pr-3">Prüfer</th>
                <th className="py-1.5 pr-3">Mechanismus</th>
                <th className="py-1.5 pr-3">Deterministisch</th>
                <th className="py-1.5">Beispiel</th>
              </tr>
            </thead>
            <tbody>
              {PRUEFER.map((p) => (
                <tr key={p.method} className="border-b border-gray-100 dark:border-gray-700/50 align-top">
                  <td className="py-1.5 pr-3">
                    <code className="text-[11px] bg-gray-100 dark:bg-gray-700 rounded px-1">{p.method}</code>
                  </td>
                  <td className="py-1.5 pr-3 text-gray-600 dark:text-gray-300">{p.mechanism}</td>
                  <td className="py-1.5 pr-3 text-gray-500">{p.deterministic}</td>
                  <td className="py-1.5 text-gray-500">{p.example}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      </section>
    </div>
  )
}
