"""Impressum-Specialist-Agent Phase-1 Prototyp.

Pattern-Match-only (kein LLM). Demonstriert die Architektur:
  - Knowledge-Base mit § 5 TMG/DDG-Pflichtangaben
  - Pattern-Library für Erkennung
  - strukturierte Findings mit Norm + Action

Phase 2 wird denselben Output produzieren, aber LLM-gestützt mit
Domain-spezifischem System-Prompt + Cross-Customer-KB.

KB-Beispiel-Einträge:
  - HR-Format DE: HR[BA] <Nr> <Stadt>
  - USt-IdNr-Format DE: DE\\d{9}
  - Aufsichtsbehörden-Liste (Branchen)
  - DSB-Adressformat
"""

from __future__ import annotations

import logging
import re

logger = logging.getLogger(__name__)


# Pflichtangaben nach § 5 TMG + § 1 DL-InfoV
PFLICHTANGABEN = {
    "name_anbieter": {
        "label": "Name + Anschrift des Anbieters",
        "norm": "§ 5 Abs. 1 Nr. 1 TMG",
        "patterns": [
            # Label-Form: "Anbieter:", "Diensteanbieter:", "Verantwortlicher:"
            re.compile(r"\b(?:Anbieter|Diensteanbieter|"
                       r"Verantwortlich(?:er Anbieter)?)\s*[:.\s]",
                       re.IGNORECASE),
            # Label-frei: Firma (Rechtsform) + Strasse + PLZ — Tesla-
            # Pattern. Wenn das Impressum ohne explizites "Anbieter:"-
            # Label direkt mit Firma+Adresse loslegt, gilt das auch.
            re.compile(
                r"\b[A-ZÄÖÜ][\w\-\& ]{1,80}?\s+"
                r"(?:GmbH|AG|UG|KG|SE|GbR|OHG|Limited|Ltd|LLC)\s*"
                r"[\s\S]{0,400}?"
                r"\b\d{5}\s+[A-ZÄÖÜ]",
                re.IGNORECASE,
            ),
        ],
        "severity_if_missing": "HIGH",
    },
    "kontakt_email": {
        "label": "Email-Adresse",
        "norm": "§ 5 Abs. 1 Nr. 2 TMG",
        "patterns": [
            re.compile(r"\b[\w.+-]+@[\w-]+\.[a-z]{2,}\b", re.IGNORECASE),
        ],
        "severity_if_missing": "HIGH",
    },
    "kontakt_telefon": {
        "label": "Telefon",
        "norm": "§ 5 Abs. 1 Nr. 2 TMG",
        "patterns": [
            re.compile(r"(?:Tel(?:efon)?|Phone)\.?\s*[:.\s]\s*[\+\d][\d\s/\-()]{5,}",
                       re.IGNORECASE),
        ],
        "severity_if_missing": "MEDIUM",
    },
    "handelsregister": {
        "label": "Handelsregister-Eintrag",
        "norm": "§ 5 Abs. 1 Nr. 4 TMG",
        "patterns": [
            re.compile(r"\bHR[BA]\s+\d", re.IGNORECASE),
            re.compile(r"Handelsregister", re.IGNORECASE),
        ],
        "severity_if_missing": "HIGH",
    },
    "ust_id": {
        "label": "USt-IdNr",
        "norm": "§ 5 Abs. 1 Nr. 6 TMG",
        "patterns": [
            re.compile(r"\b(?:USt-?Id(?:Nr)?\.?|VAT(?:-?Id)?)\s*[:.\s]",
                       re.IGNORECASE),
            re.compile(r"\bDE\d{9}\b"),
        ],
        "severity_if_missing": "MEDIUM",
    },
    "vertretungsberechtigte": {
        "label": "Vertretungsberechtigte Person",
        "norm": "§ 5 Abs. 1 Nr. 1 TMG (juristische Personen)",
        "patterns": [
            # Korrekte Label: "Geschäftsführer:", "Vertretungsberechtigt:"
            re.compile(r"(?:Gesch(?:ae|ä)ftsf(?:ue|ü)hrer|"
                       r"Vertretungsberechtigt|vertreten\s+durch)"
                       r"\s*[:.\s]",
                       re.IGNORECASE),
            # US-Konzern-Habit: "Management" als nicht-rechtskonformes
            # Alternativlabel (Tesla, Apple, etc.). Erkennen als
            # vorhanden — separater Sub-Finding meldet die Label-
            # Korrekturpflicht.
            re.compile(r"\bManagement\s*[:.\s]\s*[A-ZÄÖÜ]", re.IGNORECASE),
            re.compile(r"\bDirector(?:s|en)?\s*[:.\s]\s*[A-ZÄÖÜ]",
                       re.IGNORECASE),
        ],
        "severity_if_missing": "HIGH",
    },
    "vertretungsberechtigte_label_korrekt": {
        "label": "Korrekte Bezeichnung 'Geschäftsführer' statt 'Management'",
        "norm": "§ 5 Abs. 1 Nr. 1 TMG (Deutsch-Pflicht, gerichtsfest)",
        "patterns": [
            # PASSED nur wenn DEUTSCHES Label vorhanden.
            re.compile(r"(?:Gesch(?:ae|ä)ftsf(?:ue|ü)hrer|"
                       r"Vorstand|"
                       r"Vertretungsberechtigt|vertreten\s+durch)"
                       r"\s*[:.\s]",
                       re.IGNORECASE),
        ],
        "severity_if_missing": "MEDIUM",
    },
    "aufsichtsbehoerde": {
        "label": "Aufsichtsbehörde (regulierte Branchen)",
        "norm": "§ 5 Abs. 1 Nr. 3 TMG (Branchen-bedingt)",
        "patterns": [
            re.compile(r"Aufsichtsbeh(?:ö|oe)rde\s*[:.\s]", re.IGNORECASE),
            re.compile(
                r"\bBAFin\b|\bBNetzA\b|\bLKA\b|\bKBA\b|"
                r"Kraftfahrt-?Bundesamt|Bundesnetzagentur|"
                r"Bundesanstalt\s+f(?:ü|ue)r",
                re.IGNORECASE,
            ),
        ],
        "severity_if_missing": "LOW",
    },
    "verantwortlicher_redaktion": {
        "label": "Verantwortlicher § 18 MStV (journalistisch-redaktionell)",
        "norm": "§ 18 MStV (bei Blog/News/Magazin/Newsroom Pflicht)",
        "patterns": [
            re.compile(
                r"(?:Verantwortlich(?:er|e)?\s+(?:f(?:ue|ü)r|i\.S\.d\.|"
                r"nach|gem(?:ae|ä)ß)\s+§\s*18|"
                r"V\.i\.S\.d\.\s*§?\s*18|"
                r"redaktionell\s+Verantwortlich)",
                re.IGNORECASE,
            ),
        ],
        "severity_if_missing": "MEDIUM",
    },
    "verbraucher_streitbeilegung": {
        "label": "Verbraucher-Streitbeilegung-Hinweis",
        "norm": "§ 36 VSBG (B2C-Anbieter Pflicht)",
        "patterns": [
            re.compile(
                r"(?:Verbraucherschlichtungs|VSBG|"
                r"Streitbeilegung|"
                r"Schlichtungsstelle|"
                r"alternative\s+Streit(?:beilegung|schlichtung))",
                re.IGNORECASE,
            ),
        ],
        "severity_if_missing": "MEDIUM",
    },
    "berufsangaben": {
        "label": "Berufsbezeichnung + Berufsrechtliche Angaben",
        "norm": "§ 5 Abs. 1 Nr. 5 TMG (Kammerberufe)",
        "patterns": [
            re.compile(r"Berufsbezeichnung|Berufsordnung|Kammer",
                       re.IGNORECASE),
        ],
        "severity_if_missing": "LOW",
    },
    "odr_link": {
        "label": "OS-Link auf EU-Plattform",
        "norm": "Art. 14 EU-VO 524/2013 (B2C-Onlineshops)",
        "patterns": [
            re.compile(r"ec\.europa\.eu/consumers/odr", re.IGNORECASE),
        ],
        "severity_if_missing": "MEDIUM",
    },
}


def evaluate(impressum_text: str,
             business_scope: set[str] | None = None) -> list[dict]:
    """Run Impressum-Agent against the doc text.

    Returns a list of finding dicts; empty when all Pflichtangaben
    present. `business_scope` controls which optional checks run
    (e.g. OS-Link only for B2C ecommerce).
    """
    if not impressum_text:
        return []
    business_scope = business_scope or set()
    findings: list[dict] = []
    # Auto-detect KFZ-Hersteller / Auto-Direktvertrieb für KBA-Hint.
    # Erst: explizite Begriffe (Fahrzeug, Automobil, …).
    # Dann: bekannte Hersteller-Namen (BMW, Tesla, Mercedes, …).
    is_automotive = bool(re.search(
        r"\b(?:KFZ|Fahrzeug(?:e|herstellung|verkauf)?|Automobil|"
        r"E-Auto|Elektroauto|Auto-?Konfigurator|"
        r"Elektrofahrzeug|Hybrid-?Fahrzeug)\b",
        impressum_text, re.IGNORECASE,
    )) or bool(re.search(
        r"\b(?:Tesla|BMW|Mercedes-?Benz|Audi|Volkswagen|Porsche|"
        r"Volvo|Stellantis|Skoda|Seat|Cupra|MINI|Smart|"
        r"Opel|Ford\s+Deutschland|Hyundai|Kia|Toyota|Mazda|"
        r"Nissan|Honda|Subaru|Lexus|Polestar|NIO|BYD|Rivian|"
        r"Lucid)\s+(?:Germany|Deutschland|Group|Holding|AG|"
        r"GmbH|S(?:E|\.A\.))\b",
        impressum_text, re.IGNORECASE,
    ))
    for field_id, spec in PFLICHTANGABEN.items():
        # Skip context-dependent fields when scope doesn't match
        if field_id == "odr_link" and "ecommerce" not in business_scope:
            continue
        if field_id == "aufsichtsbehoerde" and not (
            "regulated_profession" in business_scope
            or "financial_services" in business_scope
            or "insurance" in business_scope
            or is_automotive
        ):
            continue
        if field_id == "berufsangaben" and (
            "regulated_profession" not in business_scope
        ):
            continue
        if field_id == "verantwortlicher_redaktion" and (
            "editorial" not in business_scope
        ):
            continue
        if field_id == "verbraucher_streitbeilegung" and (
            "ecommerce" not in business_scope
            and "b2c" not in business_scope
        ):
            continue
        found = any(p.search(impressum_text) for p in spec["patterns"])
        if found:
            continue
        # Context-aware action: KBA-Hint bei Auto-Branche
        action = (
            f"{spec['label']} im Impressum ergänzen "
            f"(Pflichtangabe nach {spec['norm']})."
        )
        if field_id == "aufsichtsbehoerde" and is_automotive:
            action = (
                "Aufsichtsbehörde im Impressum benennen. Für "
                "KFZ-Hersteller/-Vertrieb typisch: Kraftfahrt-"
                "Bundesamt (KBA), Fördestraße 16, 24944 Flensburg, "
                "www.kba.de. Bei Ladestrom-Vertrieb zusätzlich "
                "Bundesnetzagentur (BNetzA)."
            )
        findings.append({
            "check_id": f"IMPRESSUM-AGENT-{field_id.upper()}",
            "agent": "impressum_agent_v1",
            "field_id": field_id,
            "severity": spec["severity_if_missing"],
            "severity_reason": "missing",
            "title": f"Pflichtangabe '{spec['label']}' fehlt im Impressum",
            "norm": spec["norm"],
            "action": action,
        })
    if findings:
        logger.info(
            "impressum_agent: %d findings (kein LLM, KB v1)", len(findings),
        )
    return findings
