"""
P18 — Critical-Findings-Block fuer die Executive-Summary.

Analysiert die echten Daten (banner_checks, phases, scorecard, results) und
rendert einen ROTEN Sofortmassnahmen-Block GANZ OBEN in der Email — mit
Quellenangaben (DSK, EDPB, EuGH, Behoerden-Buessgeld-Faelle) und konkreten
Sofortmassnahmen.

Regel: Block wird nur gerendert wenn echte kritische Verstoesse vorliegen.
Bei sauberen Sites bleibt er weg.
"""

from __future__ import annotations


def _truncate_words(text: str, max_chars: int) -> str:
    """P65: Truncate at word boundary, never mid-word."""
    if not text or len(text) <= max_chars:
        return text
    cut = text[:max_chars]
    last_space = cut.rfind(" ")
    if last_space > max_chars // 2:
        cut = cut[:last_space]
    return cut.rstrip(",;:.") + "…"


# Bekannte Buessgeld-Praezedenzfaelle als Quellen-Hint
_BUSSGELD_REFS = {
    "no_provider_per_category": "CNIL France 2023 — TikTok 5 Mio EUR (fehlende Vendor-Transparenz)",
    "dse_unvollstaendig":       "BayLDA 2024 — diverse Mittelstand-Faelle, 5k–50k EUR",
    "cookie_doc_missing":       "LfDI BW 2023 — fehlende Cookie-Erklaerung, 30k EUR",
    "dark_pattern_reject":      "EDPB Guidelines 3/2022 + DSK 2024 — Bussgeldrahmen Art. 83 DSGVO",
    "schrems_ii":               "EuGH C-311/18 (Schrems II) — Bussgeldrahmen bis 4% Konzern-Umsatz",
    "impressum_im_banner":      "LG Rostock 3 O 22/19 — Impressum-Pflicht ueberlagernder Banner",
}


def _detect_critical_issues(
    banner_result: dict | None,
    scorecard: dict | None,
    results: list,
) -> list[dict]:
    """Erkenne kritische Verstoesse aus den vorliegenden Daten."""
    issues: list[dict] = []
    br = banner_result or {}
    sc = scorecard or {}

    # 1) Banner-Violations (HIGH/CRITICAL) aus consent-tester
    for v in (br.get("banner_checks") or {}).get("violations", []):
        sev = (v.get("severity") or "").upper()
        if sev in ("CRITICAL", "HIGH"):
            issues.append({
                "key": "banner_violation",
                "title": _truncate_words(v.get("text", ""), 260),
                "severity": sev,
                "action": _action_for_banner_violation(v),
                "source": v.get("legal_ref", ""),
                "bussgeld": _BUSSGELD_REFS.get("impressum_im_banner")
                            if "impressum" in (v.get("text") or "").lower()
                            else _BUSSGELD_REFS.get("dark_pattern_reject"),
            })

    # 2) Category-Tests: Banner zeigt keine Provider-Details pro Kategorie.
    # Bevorzugt das echte Signal aus dem Click-Through-Test (P19):
    # provider_details_visible. Fallback: leere tracking_services.
    cat_tests = br.get("category_tests") or []
    cats_without_details = [
        c for c in cat_tests
        if c.get("category") != "necessary"
        and (c.get("provider_details_visible") is False
             or (c.get("provider_details_visible") is None
                 and not c.get("tracking_services")))
    ]
    if cats_without_details and len(cat_tests) >= 2:
        cats = ", ".join(c.get("category_label", c.get("category", "?"))
                         for c in cats_without_details)
        issues.append({
            "key": "no_provider_per_category",
            "title": f"Cookie-Banner: Kategorien ({cats}) zeigen keine "
                     f"Provider-/Cookie-Details",
            "severity": "HIGH",
            "action": ("Pro Banner-Kategorie eine Liste der eingebundenen "
                       "Anbieter + Cookie-Details (Name, Zweck, Speicherdauer, "
                       "Drittlandtransfer) sichtbar machen — am besten als "
                       "ausklappbares Detail-Panel. Sonst ist die "
                       "Einwilligung nicht 'informiert' nach Art. 7 DSGVO "
                       "und gilt als unwirksam."),
            "source": "Art. 7 Abs. 1 DSGVO, EDPB Guidelines 2/2023, DSK 2024",
            "bussgeld": _BUSSGELD_REFS["no_provider_per_category"],
        })

    # 3) DSGVO/TDDDG-Score < 30%: DSE rechtswidrig
    pct = int((sc.get("totals") or {}).get("pct", 100))
    if pct and pct < 30:
        issues.append({
            "key": "dse_unvollstaendig",
            "title": f"Datenschutzerklaerung erfuellt nur {pct}% der Pflichten",
            "severity": "HIGH",
            "action": ("Vollstaendig nach Art. 13 DSGVO ueberarbeiten: "
                       "Verantwortlicher, Zwecke, Rechtsgrundlage, "
                       "Speicherdauer, Drittland-Transfers, alle Betroffenen-"
                       "rechte, konkrete Aufsichtsbehoerde."),
            "source": "Art. 13 DSGVO + Art. 14 (alternativ), DSK-OH Telemedien 2024",
            "bussgeld": _BUSSGELD_REFS["dse_unvollstaendig"],
        })

    # 4) Cookie-Richtlinie fehlt komplett (nicht erreichbar)
    cookie_missing = any(
        (r.doc_type == "cookie" if hasattr(r, "doc_type") else
         r.get("doc_type") == "cookie")
        and ((r.error if hasattr(r, "error") else r.get("error", "")) or "")
        .startswith("Auf der Website nicht gefunden")
        for r in (results or [])
    )
    cookie_deduped = any(
        (r.doc_type == "cookie" if hasattr(r, "doc_type") else
         r.get("doc_type") == "cookie")
        and "Nicht separat vorhanden" in
        ((r.error if hasattr(r, "error") else r.get("error", "")) or "")
        for r in (results or [])
    )
    if cookie_missing or cookie_deduped:
        issues.append({
            "key": "cookie_doc_missing",
            "title": ("Keine eigenstaendige Cookie-Richtlinie"
                      if cookie_deduped
                      else "Cookie-Richtlinie nicht auffindbar"),
            "severity": "HIGH",
            "action": ("Separate Cookie-Richtlinie-Seite erstellen mit "
                       "tabellarischer Auflistung aller Cookies (Name, "
                       "Anbieter, Zweck, Speicherdauer, Drittlandtransfer). "
                       "Direkt aus dem Banner verlinken."),
            "source": "Art. 13 DSGVO, §25 TDDDG, DSK-OH Telemedien 2024",
            "bussgeld": _BUSSGELD_REFS["cookie_doc_missing"],
        })

    # 5) Schrems-II-Risiko: Google/Meta/Microsoft im Banner, aber keine SCC/DPF
    #    Detection: pre-/post-consent-cookies in den phases enthalten US-Tracker
    phases = br.get("phases") or {}
    has_us_tracker = False
    for ph in phases.values():
        if not isinstance(ph, dict):
            continue
        for t in (ph.get("tracking_services") or []):
            if isinstance(t, dict):
                name = (t.get("name", "") or "").lower()
            else:
                name = str(t).lower()
            if any(w in name for w in ("google", "meta", "facebook",
                                       "microsoft", "linkedin", "tiktok")):
                has_us_tracker = True
                break
    if has_us_tracker:
        issues.append({
            "key": "schrems_ii",
            "title": "US-Tracker geladen — Schrems-II-Risiko",
            "severity": "HIGH",
            "action": ("Pro Drittland-Anbieter dokumentieren: SCC (Art. 46 "
                       "DSGVO) ODER DPF-Zertifizierung pruefen + in der "
                       "Datenschutzerklaerung explizit benennen."),
            "source": "Art. 44 ff. DSGVO, EuGH C-311/18 (Schrems II)",
            "bussgeld": _BUSSGELD_REFS["schrems_ii"],
        })

    return issues


def _action_for_banner_violation(v: dict) -> str:
    text = (v.get("text") or "").lower()
    if "impressum" in text:
        return ("Impressum-Link direkt im Banner ergaenzen — bei "
                "ueberlagerndem Banner Pflicht nach §5 TMG.")
    if "ablehnen" in text or "dark pattern" in text:
        return ("'Ablehnen'-Button visuell gleichwertig zu 'Akzeptieren' "
                "gestalten (gleiche Groesse, Farbe, Position).")
    if "widerruf" in text or "cookie-einstellungen" in text:
        return ("Floating-Icon oder Footer-Link 'Cookie-Einstellungen' "
                "permanent einblenden — Widerruf so einfach wie Erteilung.")
    return ("Banner-Verstoss beheben gemaess der genannten Rechtsgrundlage.")


def build_critical_findings_html(
    banner_result: dict | None,
    scorecard: dict | None,
    results: list,
) -> str:
    """Render der Audit-Zusammenfassung fuer die Geschaeftsfuehrung.

    P89: Co-Pilot-Tonalitaet statt Panik-Rot.
    - Sachlich blau statt alarmistisch rot
    - "Themen die besprochen werden sollten" statt "VERSTOESSE"
    - Realistische Zeitschaetzung (4-8 Wochen)
    - Buessgeld-Risiko in separater, dezenter Section ganz unten
    - Konfidenz-Hinweis "False-Positives moeglich"
    """
    issues = _detect_critical_issues(banner_result, scorecard, results)
    if not issues:
        return ""

    items = []
    for idx, i in enumerate(issues, 1):
        # P87-Vorbereitung: keine HIGH-Badges mehr — wir nummerieren stattdessen
        items.append(
            f'<div style="margin-bottom:10px;padding:10px 14px;'
            f'background:#fff;border-radius:6px;'
            f'border-left:3px solid #2563eb">'
            f'<div style="font-size:13px;font-weight:600;color:#1e293b;'
            f'margin-bottom:4px">'
            f'<span style="display:inline-block;background:#dbeafe;color:#1e40af;'
            f'padding:1px 8px;border-radius:10px;font-size:10px;'
            f'margin-right:8px;font-weight:600">Thema {idx}</span>'
            f'{i["title"]}</div>'
            f'<div style="font-size:11px;color:#475569;margin-top:6px">'
            f'<strong>Empfehlung:</strong> {i["action"]}</div>'
            f'<div style="font-size:10px;color:#94a3b8;margin-top:4px;'
            f'font-style:italic">Hintergrund: {i.get("source","")}</div>'
            f'</div>'
        )

    n = len(issues)
    plural = "Themen" if n != 1 else "Thema"
    return (
        '<div style="font-family:-apple-system,BlinkMacSystemFont,sans-serif;'
        'max-width:700px;margin:0 auto 18px;padding:18px 22px;'
        'background:#f0f9ff;border:1px solid #bfdbfe;border-radius:10px">'
        '<div style="font-size:11px;color:#1e40af;text-transform:uppercase;'
        'letter-spacing:1.2px;margin-bottom:4px;font-weight:600">'
        'Zusammenfassung fuer die Geschaeftsfuehrung</div>'
        f'<h2 style="margin:0 0 8px;font-size:18px;color:#1e293b">'
        f'{n} {plural} zur Besprechung mit DSB, Marketing und Entwicklung</h2>'
        '<p style="margin:0 0 14px;font-size:12px;color:#475569;line-height:1.5">'
        'Wir haben Datenschutzerklaerung, Cookie-Banner, Impressum und '
        'eingebundene Anbieter technisch analysiert. Die folgenden Punkte '
        'sollten in den naechsten Wochen geklaert werden &mdash; typische '
        'Umsetzungsdauer 4-8 Wochen (DSB-Review &rarr; Marketing-Agentur '
        '&rarr; Entwicklung &rarr; Freigabe). Detaillierte technische '
        'Analyse mit weiteren Findings finden Sie unten.</p>'
        + "".join(items) +
        '<div style="margin-top:14px;padding:10px 12px;background:#f1f5f9;'
        'border-radius:6px;font-size:10px;color:#64748b;line-height:1.5">'
        '<strong style="color:#475569">Hinweis:</strong> Automatisierte '
        'Audits enthalten False-Positives. Wo unsicher, bitte mit DSB pruefen '
        'oder uns Feedback geben &mdash; wir lernen daraus. '
        'Rechtliche Risiken (Bussgeld-Rahmen Art. 83 DSGVO bis 4&nbsp;% des '
        'weltweiten Jahresumsatzes, realistisch 0,1-1&nbsp;% bei Erstverstoss '
        'nach CNIL/LfDI-Massstab) werden weiter unten pro Finding eingeordnet.'
        '</div>'
        '</div>'
    )
