"""Cross-Browser-Befunde — deterministische Sicht über die Browser-Matrix.

KEINE zweite Engine, kein LLM: rein eine Auswertung der bereits vom
consent-tester gemessenen Per-Engine-Ergebnisse (siehe
[[feedback_agents_delegate_not_reimplement]]). Findet Inkonsistenzen ZWISCHEN
den Browsern und ordnet sie ein — der zentrale Mehrwert gegenüber einem
Einzel-Browser-Scan:

  * Cookies vor Consent / „Ablehnen“ nicht universell respektiert?
  * Browser-Tracking-Schutz (Safari/ITP, Brave/Shields, Firefox/ETP)
    maskiert Verstöße clientseitig → ein „sauberes" Ergebnis in einer
    strengen Engine ist KEIN Compliance-Beleg; maßgeblich sind die
    nachgiebigen Engines (Chrome/Edge/Chromium), in denen tatsächlich
    gesetzt wird.
"""

from __future__ import annotations

from typing import Any

# Welcher Browser-Schutzmechanismus greift je Profil — für die Einordnung,
# warum sich Engines unterscheiden (nicht zum Bewerten der Compliance).
_PROTECTION = [
    ("brave", "Brave-Shields"),
    ("webkit", "Safari/ITP"),
    ("iphone", "Safari/ITP"),
    ("safari", "Safari/ITP"),
    ("firefox", "Firefox/ETP"),
    ("gecko", "Firefox/ETP"),
]


def _protection_label(row: dict) -> str:
    key = f"{row.get('profile_id', '')} {row.get('engine', '')}".lower()
    for needle, label in _PROTECTION:
        if needle in key:
            return label
    return ""  # blink/chrome/edge = nachgiebig (kein client-seitiger Schutz)


def _labels(rows: list[dict]) -> list[str]:
    return [r.get("label") or r.get("profile_id") or "?" for r in rows]


def build_cross_findings(matrix: dict | None) -> list[dict]:
    """Liefert eine priorisierte Liste von Cross-Browser-Befunden.

    Befund-Form: {title, detail, severity, affected: [labels], measure}.
    Nur Engines MIT Messdaten werden verglichen (Fehler-/„nicht verfügbar"-
    Zeilen fließen nur als Coverage-Hinweis ein)."""
    rows_all = (matrix or {}).get("browser_matrix") or []
    data = [r for r in rows_all if r.get("summary")]
    missing = [r for r in rows_all if not r.get("summary")]
    out: list[dict] = []
    if not data:
        return out

    def _s(r: dict) -> dict:
        return r.get("summary") or {}

    def _pre_track(r: dict) -> int:
        # Nicht-essentielles TRACKING vor Consent (§ 25 Abs. 1 TDDDG) — das
        # rechtlich relevante Signal. NICHT die Cookie-Rohzahl: die enthaelt
        # technisch notwendige Cookies inkl. des Consent-Cookies selbst (das
        # speichern MUSS, dass abgelehnt wurde) → § 25 Abs. 2, einwilligungsfrei.
        return (_s(r).get("violations") or {}).get("before_consent") or 0

    track_yes = [r for r in data if _pre_track(r) > 0]
    track_no = [r for r in data if _pre_track(r) == 0]
    rej_bad = [r for r in data if _s(r).get("reject_respected") is False]
    rej_ok = [r for r in data if _s(r).get("reject_respected") is True]

    # ── Tracking VOR der Einwilligung (nicht: jede Cookie-Rohzahl) ────────
    _ESS = (" Technisch notwendige Cookies inkl. des Consent-Cookies sind "
            "ausgenommen (§ 25 Abs. 2 TDDDG).")
    if track_yes and not track_no:
        out.append({
            "title": "Tracking vor der Einwilligung — in allen Browsern",
            "detail": "In jeder getesteten Engine feuern vor einer aktiven "
                      "Einwilligung nicht-essentielle Tracker." + _ESS,
            "severity": "HIGH",
            "affected": _labels(track_yes),
            "measure": "Tracking-/Marketing-Skripte erst nach aktiver "
                       "Einwilligung laden (§ 25 Abs. 1 TDDDG).",
        })
    elif track_yes and track_no:
        masked = sorted({_protection_label(r) for r in track_no if _protection_label(r)})
        hint = (f" Die unauffälligen Engines ({', '.join(_labels(track_no))}) "
                f"unterdrücken die Tracker vermutlich clientseitig "
                f"({', '.join(masked)}) — das ist KEIN Compliance-Beleg."
                if masked else "")
        out.append({
            "title": "Tracking vor Einwilligung — nur in manchen Browsern",
            "detail": f"Nicht-essentielle Tracker vor Consent in "
                      f"{', '.join(_labels(track_yes))}, nicht in "
                      f"{', '.join(_labels(track_no))}.{hint}",
            "severity": "HIGH",
            "affected": _labels(track_yes),
            "measure": "Server-/skriptseitig auf Consent gaten statt auf den "
                       "Tracking-Schutz einzelner Browser zu vertrauen.",
        })

    # ── „Ablehnen“ respektiert? ──────────────────────────────────────────
    if rej_bad and not rej_ok:
        out.append({
            "title": "„Ablehnen“ wird in keinem Browser respektiert",
            "detail": "Nach Klick auf „Ablehnen“ verbleiben in jeder Engine "
                      "Verstöße oder neue Tracker.",
            "severity": "HIGH",
            "affected": _labels(rej_bad),
            "measure": "Reject-Handler muss alle nicht-essentiellen Skripte/"
                       "Cookies tatsächlich stoppen (Art. 7 Abs. 3 DSGVO).",
        })
    elif rej_bad and rej_ok:
        masked = sorted({_protection_label(r) for r in rej_ok if _protection_label(r)})
        hint = (f" Dass {', '.join(_labels(rej_ok))} sauber wirken, liegt "
                f"vermutlich am Browser-Schutz ({', '.join(masked)}), nicht am "
                f"Banner." if masked else "")
        out.append({
            "title": "„Ablehnen“ wird nicht in allen Browsern respektiert",
            "detail": f"Verstoß nach Ablehnen in {', '.join(_labels(rej_bad))}; "
                      f"sauber in {', '.join(_labels(rej_ok))}.{hint}",
            "severity": "HIGH",
            "affected": _labels(rej_bad),
            "measure": "Reject-Handler universell wirksam machen — unabhängig "
                       "vom Tracking-Schutz des Browsers.",
        })

    # Hinweis: Impressum/DSE-Link-im-Banner wird NICHT mehr hier als pauschales
    # MEDIUM geflaggt. Der per-Engine-Check (banner_text_checker) ist footer-
    # bewusst: ist der Footer-Link trotz Banner erreichbar → LOW/Best Practice
    # statt Verstoss. Doppel-/Falsch-Flag hier vermieden.

    # ── Consent-Historie / Widerruf (Best Practice, #62) ─────────────────
    ch_rows = [(_s(r).get("consent_history") or {}) for r in data]
    any_history = any(c.get("history_capable") for c in ch_rows)
    any_withdraw = any(c.get("withdraw_ui") for c in ch_rows)
    provider = next((c.get("provider") for c in ch_rows if c.get("provider")), "")
    if any_history or any_withdraw:
        bits = []
        if provider:
            bits.append(f"Anbieter: {provider}")
        if any_history:
            bits.append("versionierte Einwilligung (nachvollziehbar)")
        if any_withdraw:
            bits.append("Widerruf-/Einstellungs-Widget vorhanden")
        out.append({
            "title": "Einwilligungs-Historie / Widerruf vorhanden",
            "detail": "Positiv: " + ", ".join(bits) + ". Nutzer können "
                      "nachvollziehen bzw. ändern, welcher Version sie zugestimmt "
                      "haben.",
            "severity": "LOW", "affected": _labels(data),
            "measure": "Beibehalten.",
        })
    else:
        out.append({
            "title": "Keine sichtbare Einwilligungs-Historie",
            "detail": "Weder eine versionierte Consent-Historie noch ein "
                      "dauerhaftes Widerruf-Widget erkannt.",
            "severity": "LOW", "affected": _labels(data),
            "measure": "Best Practice: Consent-Historie + jederzeit erreichbares "
                       "Widerruf-/Einstellungs-Widget anbieten (Borlabs-Stil) — "
                       "Nutzer sehen, wann sie welcher Version zugestimmt haben.",
        })

    # ── Coverage-Hinweis: nicht getestete Browser ────────────────────────
    if missing:
        out.append({
            "title": "Nicht alle Browser getestet",
            "detail": f"{len(missing)} Browser nicht verfügbar "
                      f"({', '.join(_labels(missing))}). Echtes Brave/Chrome/"
                      f"Edge laufen nur auf dem amd64-Server, nicht in der "
                      f"arm64-Dev-Umgebung.",
            "severity": "LOW", "affected": _labels(missing),
            "measure": "Für vollständige Abdeckung auf dem Produktiv-Server "
                       "(amd64) testen.",
        })

    return out
