"""
P54 — Diff-Banner fuer End-User (USP-Feature).

USP-Idee: bei wiederkehrenden Besuchern zeigt das Banner NICHT die
Standard-Frage, sondern eine Diff-Mitteilung:
   "Seit deiner letzten Zustimmung haben wir hinzugefuegt:
    * Microsoft Bing (Werbung)
    * TikTok Pixel (Marketing)
    Bitte erneut zustimmen oder anpassen."

Backend-Seite (hier): liefert pro Snapshot eine 'diff_for_user'-Struktur
die zum Embedden in eigenen Banner / Hinweistext genutzt werden kann.
Frontend-Banner-Lib (separate consent-sdk) konsumiert das.

Vergleicht Vendor-Listen zwischen aktuellem Snapshot und dem letzten
Snapshot mit gleicher site_domain.
"""

from __future__ import annotations

import logging
from typing import Iterable

from sqlalchemy import text as sa_text
from sqlalchemy.orm import Session

logger = logging.getLogger(__name__)


def _norm_vendor_set(vendors: Iterable) -> set[str]:
    out: set[str] = set()
    for v in (vendors or []):
        if isinstance(v, dict):
            n = (v.get("name") or "").strip()
        elif isinstance(v, str):
            n = v.strip()
        else:
            continue
        if n:
            out.add(n)
    return out


def compute_user_facing_diff(
    db: Session,
    site_domain: str,
    current_check_id: str,
    current_cmp_vendors: list,
) -> dict | None:
    """Vergleicht aktuelle vs letzte cmp_vendors-Liste fuer die gleiche
    site_domain. Liefert {prev_at, added_vendors, removed_vendors,
    new_high_risk_categories} oder None wenn kein vorheriger Lauf."""
    if not site_domain:
        return None
    try:
        row = db.execute(sa_text(
            """
            SELECT cmp_vendors, created_at
            FROM compliance.compliance_check_snapshots
            WHERE site_domain = :dom AND check_id != :ex
            ORDER BY created_at DESC LIMIT 1
            """
        ), {"dom": site_domain, "ex": current_check_id}).fetchone()
    except Exception as e:
        logger.warning("diff lookup failed: %s", e)
        return None
    if not row:
        return None

    prev_vendors = row[0] or []
    prev_at = row[1]
    curr_set = _norm_vendor_set(current_cmp_vendors)
    prev_set = _norm_vendor_set(prev_vendors)

    added = sorted(curr_set - prev_set)
    removed = sorted(prev_set - curr_set)
    if not added and not removed:
        return None

    # High-risk Kategorien aus added Vendors: Marketing / Tracking
    new_marketing: list[str] = []
    for v in current_cmp_vendors:
        if not isinstance(v, dict):
            continue
        n = (v.get("name") or "").strip()
        cat = (v.get("category") or "").lower()
        if n in added and cat in ("marketing", "tracking", "advertising"):
            new_marketing.append(n)

    return {
        "prev_at":              prev_at.isoformat() if prev_at else None,
        "added_vendors":        added,
        "removed_vendors":      removed,
        "new_marketing_vendors": new_marketing,
        "requires_reconsent":   bool(new_marketing),
    }


def build_diff_banner_snippet(diff: dict) -> str:
    """Liefert HTML-Snippet das der Site-Betreiber in seinen eigenen
    Cookie-Banner einbauen kann (z.B. via consent-sdk)."""
    if not diff or not diff.get("added_vendors"):
        return ""
    added = diff.get("added_vendors", [])
    n_marketing = len(diff.get("new_marketing_vendors") or [])
    items = "".join(f"<li>{v}</li>" for v in added[:8])
    reconsent_note = ""
    if diff.get("requires_reconsent"):
        reconsent_note = (
            f'<p style="margin:6px 0 0;color:#991b1b;font-size:12px">'
            f'<strong>{n_marketing} neue{"r" if n_marketing == 1 else ""} '
            f'Marketing-Anbieter</strong> seit Ihrer letzten Zustimmung — '
            'bitte erneut bestaetigen.'
            '</p>'
        )
    return (
        '<div class="breakpilot-consent-diff" '
        'style="font-family:-apple-system,sans-serif;font-size:12px;'
        'padding:8px 12px;background:#fef3c7;border:1px solid #fde68a;'
        'border-radius:6px;margin-bottom:8px">'
        '<strong>Seit Ihrer letzten Zustimmung haben wir hinzugefuegt:</strong>'
        f'<ul style="margin:4px 0 0 18px;padding:0">{items}</ul>'
        + reconsent_note +
        '</div>'
    )
