"""
P87 — Konfidenz-Score pro Finding.

Nicht jedes HIGH-Finding ist gleich sicher. "Kein Reject-Button im Banner"
ist faktisch direkt beobachtbar (Confidence ~98%). "DSE enthaelt keinen
DSB-Kontakt" ist ein Textmuster-Match und kann False-Positive sein
(Confidence ~70%). "Cookie X als essential deklariert, Library sagt
marketing" haengt von Library-Qualitaet ab (Confidence ~80%).

Liefert pro Finding-Label ein (confidence_pct, reason) Paar. Wird im
Mail-Render als kleine graue Klammer hinter dem Severity-Pill angezeigt:
"HOCH (95% Konfidenz: Direkt im DOM beobachtet)".

Keine ML — nur regelbasiert. Eine zentrale Stelle damit alle Render-
Stellen einheitlich klassifizieren.
"""

from __future__ import annotations

import re

# (regex, confidence_pct, reason)
# Reihenfolge wichtig: spezifischere Patterns zuerst.
_RULES: list[tuple[re.Pattern, int, str]] = [
    # 1) Direkt im DOM / im Cookie-Jar beobachtet — sehr hohe Sicherheit
    (re.compile(r"reject[- ]?button.*(fehlt|nicht.*vorhanden)", re.I), 98,
     "Direkt im Banner-DOM ueberprueft"),
    (re.compile(r"(anpassen|einstellungen|customize).*button.*fehlt", re.I), 95,
     "Initial-Banner-DOM ueberprueft"),
    (re.compile(r"cookie.*vor.*einwilligung.*gesetzt", re.I), 96,
     "Cookie-Jar vor Akzeptieren beobachtet"),
    (re.compile(r"(tracking|marketing).*ohne.*einwilligung", re.I), 92,
     "Network-Calls vor Akzeptieren beobachtet"),

    # 2) Library-Mismatches — abhaengig von Library-Qualitaet
    (re.compile(r"deklariert als.*library.*sagt", re.I), 82,
     "Vergleich mit ~2.300-Cookie-Library + Open-Cookie-DB"),
    (re.compile(r"library.*marketing", re.I), 82,
     "Cookie-Library-Klassifikation"),

    # 3) Pflichtangaben-Checks (Impressum/AGB/DSE) — Textmuster, MEDIUM-Sicherheit
    (re.compile(r"impressum.*(fehlt|unvollstaendig)", re.I), 88,
     "Pattern-Match auf Impressums-Pflichtfelder (§ 5 TMG)"),
    (re.compile(r"dsb.*(fehlt|nicht.*genannt)", re.I), 75,
     "Textmuster-Suche; DSB kann ueber Impressum referenziert sein"),
    (re.compile(r"drittland.*(fehlt|nicht.*genannt|ohne.*hinweis)", re.I), 80,
     "Pattern-Match auf typische Drittland-Klauseln"),
    (re.compile(r"widerruf.*(fehlt|unvollstaendig)", re.I), 85,
     "Pattern-Match auf Widerrufsbelehrungs-Pflichtfelder"),

    # 4) Anti-Auditing-Detection — heuristisch
    (re.compile(r"anti[- ]?audit", re.I), 70,
     "Skript-Domain-Heuristik; manuelle Pruefung empfohlen"),

    # 5) Generische Konsistenz-Findings (DSE vs. Banner vs. Cookie-Liste)
    (re.compile(r"banner.*nennt.*\d+.*cmp.*\d+", re.I), 90,
     "Quantitativer Vergleich zwischen Banner-Text und CMP-Payload"),

    # 6) Klassifikations- / Kontext-Findings (Wizard-getrieben)
    (re.compile(r"(branchen|scope).*passt.*nicht", re.I), 88,
     "Wizard-Klassifikation + MC-scope_doc_type"),
]

_DEFAULT_CONFIDENCE = 78
_DEFAULT_REASON = (
    "Standard-Regelpruefung; Bestaetigung mit DSB / interner Doku empfohlen"
)


def score_finding(label: str) -> tuple[int, str]:
    """Returns (confidence_pct, reason) for a finding label."""
    if not label:
        return _DEFAULT_CONFIDENCE, _DEFAULT_REASON
    for pat, conf, reason in _RULES:
        if pat.search(label):
            return conf, reason
    return _DEFAULT_CONFIDENCE, _DEFAULT_REASON


def confidence_pill_html(label: str) -> str:
    """Returns an inline HTML snippet '(NN% Konfidenz: ...)' or empty."""
    conf, reason = score_finding(label)
    return (
        f' <span style="color:#94a3b8;font-size:10px" title="{reason}">'
        f'({conf}% Konfidenz)</span>'
    )
