"""
A — Audit-Transparenz / Audit-Quality-Checks.

Wenn der Crawler nicht alles gefunden hat, MUSS die Mail das prominent
zeigen — sonst denkt der User 'alles gut' obwohl die Datenlage Luecken
hat.

Erkennt 4 Quality-Failures:
1. banner_detected=False trotz vorhandenem Cookie-Doc → CMP-Tool ungeladen
2. cookie_doc >= 30k chars aber cmp_vendors < 10 → Vendor-Extract unvollstaendig
3. doc_text submitted aber 0 chars geladen → Crawler-Failure
4. cmp_vendors > 0 aber alle aus llm_cascade ohne Library-Match → vermutl. unvollstaendig

Diese Findings landen IMMER im GF-1-Pager (auch wenn kein anderes
HIGH-Finding da ist) — sie sagen "die Datenlage ist unvollstaendig,
manuelle Pruefung empfohlen".
"""

from __future__ import annotations

import logging

logger = logging.getLogger(__name__)


def _word_count(text: str | None) -> int:
    if not text:
        return 0
    return len(text.split())


def check_banner_not_detected(
    banner_result: dict | None,
    cookie_doc_text: str | None,
) -> dict | None:
    """1) Banner nicht geladen aber Cookie-Doc vorhanden → CMP-Tool kaputt."""
    if not isinstance(banner_result, dict):
        return None
    detected = banner_result.get("banner_detected")
    if detected is None or detected is True:
        return None
    if not cookie_doc_text or len(cookie_doc_text) < 5000:
        return None
    return {
        "severity": "HIGH",
        "code": "audit_banner_not_detected",
        "label": "Audit-Vorbehalt: Cookie-Banner konnte vom Crawler nicht "
                 "geladen werden",
        "area": "Cookie-Banner",
        "owner": "DSB + Marketing/CMP-Admin",
        "detail": (
            "Unser Crawler konnte das CMP-Tool dieser Site nicht analysieren — "
            "weder Vendor-Liste noch Cookie-Verhalten konnten geprueft werden. "
            "Moegliche Ursachen: Anti-Bot-Schutz (Akamai/Cloudflare/DataDome) "
            "blockiert Playwright; das CMP-Skript laed nur fuer bestimmte "
            "Geo-Regionen; ein neues CMP-Tool das wir noch nicht unterstuetzen. "
            "Empfehlung: manuelle Pruefung des Banners durch DSB, alternativ "
            "Cookie-Tabelle im Audit-Tool direkt einfuegen (Copy-Paste-Modus)."
        ),
        "legal_basis": "Art. 5 (2) DSGVO Rechenschaftspflicht — der Audit-"
                       "Befund muss transparent zwischen 'geprueft & OK' und "
                       "'nicht pruefbar' unterscheiden.",
    }


def check_vendor_extract_incomplete(
    cookie_doc_text: str | None,
    cmp_vendors: list | None,
) -> dict | None:
    """2) Cookie-Doc gross aber wenig Vendors → Extract unvollstaendig.

    Dynamische Schwelle nach Doc-Groesse:
    *  3k-6k Wörter   → mind. 10 Vendors erwartet
    *  6k-10k Wörter  → mind. 20 Vendors
    * 10k-15k Wörter  → mind. 30 Vendors
    *    15k+ Wörter  → mind. 40 Vendors
    """
    wc = _word_count(cookie_doc_text)
    n_vendors = len(cmp_vendors or [])
    if wc < 3000:
        return None
    # Erwartete Vendor-Anzahl heuristisch nach Doc-Groesse
    if wc >= 15000:
        expected = 40
    elif wc >= 10000:
        expected = 30
    elif wc >= 6000:
        expected = 20
    else:
        expected = 10
    if n_vendors >= expected:
        return None
    return {
        "severity": "HIGH" if wc >= 8000 else "MEDIUM",
        "code": "audit_vendor_extract_thin",
        "label": (
            f"Audit-Vorbehalt: Cookie-Richtlinie hat {wc:,} Wörter, "
            f"erwartet ~{expected} Vendors, extrahiert nur {n_vendors}"
        ).replace(",", "."),
        "area": "Vendor-Liste / VVT",
        "owner": "DSB + Marketing",
        "detail": (
            f"Bei einer Cookie-Richtlinie mit {wc:,} Woertern erwarten wir "
            f"typischerweise {expected}+ unique Vendors. Die extrahierte Zahl "
            f"({n_vendors}) ist auffaellig niedrig — entweder hat unser "
            "Parser/LLM die Tabelle nicht vollstaendig erfasst oder "
            "Vendors wurden zu konservativ erkannt. Empfehlung: Cookie-"
            "Tabelle im Copy-Paste-Modus einreichen (Frontend-Toggle "
            "'Text einfuegen' pro Cookie-Doc-Zeile) — dort parsen wir "
            "Spalten deterministisch."
        ).replace(",", "."),
        "legal_basis": "Art. 13(1)(e) DSGVO — die Empfaengerliste muss "
                       "vollstaendig sein; ein unvollstaendiger Audit darf "
                       "nicht als vollstaendig dargestellt werden.",
    }


def check_url_fetch_failed(doc_entries: list | None) -> list[dict]:
    """3) Submitted URL aber 0 oder Mini-Text → Crawler-Failure pro Doc."""
    out: list[dict] = []
    for e in (doc_entries or []):
        if not isinstance(e, dict):
            continue
        url = (e.get("url") or "").strip()
        text = (e.get("text") or "").strip()
        if not url or len(text) >= 200 or e.get("auto_discovered"):
            continue
        dt = e.get("doc_type", "doc")
        rejected = e.get("rejected_url") or ""
        out.append({
            "severity": "MEDIUM",
            "code": f"audit_url_fetch_failed_{dt}",
            "label": (
                f"Audit-Vorbehalt: {dt}-URL konnte nicht geladen werden "
                f"({len(text)} Zeichen extrahiert)"
            ),
            "area": dt,
            "owner": "DSB + Web-Team",
            "detail": (
                f"Die eingegebene URL {url[:120]} lieferte weniger als 200 "
                "Zeichen. Moegliche Ursachen: 404, JS-only Render, Anti-Bot, "
                "Cookie-Wall. Auto-Discovery hat versucht eine Alternative "
                "auf der Homepage zu finden — ohne Erfolg. Empfehlung: "
                "korrekte URL pruefen oder den Text direkt einfuegen "
                "(Copy-Paste-Modus)."
            ),
            "legal_basis": "Art. 5 (2) DSGVO Rechenschaftspflicht.",
        })
    return out


def run_all(
    banner_result: dict | None,
    cookie_doc_text: str | None,
    cmp_vendors: list | None,
    doc_entries: list | None,
) -> list[dict]:
    findings: list[dict] = []
    try:
        f1 = check_banner_not_detected(banner_result, cookie_doc_text)
        if f1:
            findings.append(f1)
    except Exception as e:
        logger.warning("audit_banner_not_detected failed: %s", e)
    try:
        f2 = check_vendor_extract_incomplete(cookie_doc_text, cmp_vendors)
        if f2:
            findings.append(f2)
    except Exception as e:
        logger.warning("audit_vendor_extract_thin failed: %s", e)
    try:
        findings.extend(check_url_fetch_failed(doc_entries))
    except Exception as e:
        logger.warning("audit_url_fetch_failed failed: %s", e)
    return findings


def build_audit_quality_block_html(findings: list[dict]) -> str:
    if not findings:
        return ""
    items: list[str] = []
    for f in findings:
        sev = f.get("severity", "MEDIUM")
        sev_color = "#dc2626" if sev == "HIGH" else "#d97706"
        items.append(
            f'<li style="margin-bottom:10px;font-size:11px;line-height:1.5">'
            f'<strong style="color:{sev_color}">[{sev}] {f.get("label","")}</strong>'
            f'<div style="color:#475569;margin-top:3px">{f.get("detail","")}</div>'
            f'<div style="color:#94a3b8;margin-top:2px;font-style:italic">'
            f'{f.get("legal_basis","")}</div>'
            f'</li>'
        )
    return (
        '<div style="font-family:-apple-system,BlinkMacSystemFont,sans-serif;'
        'max-width:760px;margin:0 auto 16px;padding:14px 18px;'
        'background:#fee2e2;border:1px solid #fecaca;border-radius:8px">'
        '<div style="font-size:11px;color:#991b1b;text-transform:uppercase;'
        'letter-spacing:1.2px;margin-bottom:4px;font-weight:600">'
        'Audit-Vorbehalt — Datenlage unvollstaendig</div>'
        f'<h3 style="margin:0 0 6px;font-size:14px;color:#1e293b">'
        f'{len(findings)} Punkt'
        f'{"e" if len(findings) != 1 else ""} bei denen der Audit selbst '
        f'an Grenzen gestossen ist</h3>'
        '<p style="margin:0 0 10px;font-size:11px;color:#475569;line-height:1.5">'
        'Die folgenden Punkte betreffen NICHT die Compliance Ihrer Website, '
        'sondern die Vollstaendigkeit unserer Pruefung. Bei diesen Bereichen '
        'sollten Sie den Audit nicht als "alles ok" werten, sondern manuell '
        'oder im Copy-Paste-Modus nachpruefen.'
        '</p>'
        '<ul style="margin:0 0 0 18px;padding:0">'
        + "".join(items) +
        '</ul></div>'
    )
