"""Phase C-2 — Browser-Matrix Multi-Browser Scan (Stage 1.c).

After the single-browser scan in Phase C, optionally fan out to the
consent-tester /scan-matrix endpoint that runs the same probe on
chromium / firefox / webkit / mobile-safari and returns a worst-of
robustness score per browser.

Activated by env `BROWSER_MATRIX=true`. Default off so existing
runs aren't slowed down 4× while we tune.

The state gets these new keys:

  state["browser_matrix"]      list[dict]  per-profile results
  state["browser_aggregate"]   dict        worst/best score + verbal
  state["browser_matrix_html"] str         pre-rendered V2 block
"""

from __future__ import annotations

import logging
import os
from html import escape as h

import httpx

from ._constants import CONSENT_TESTER_URL
from ._helpers import _update

logger = logging.getLogger(__name__)


async def run_phase_c2(state: dict) -> None:
    if os.environ.get("BROWSER_MATRIX", "false").lower() not in (
        "true", "1", "yes", "on",
    ):
        return
    check_id = state["check_id"]
    req = state["req"]
    banner_url = ""
    for d in req.documents:
        if d.url:
            from urllib.parse import urlparse
            p = urlparse(d.url)
            if p.scheme and p.netloc:
                banner_url = f"{p.scheme}://{p.netloc}"
                break
    if not banner_url:
        return

    _update(check_id, "Browser-Matrix: Multi-Engine-Scan...", 83)

    profiles_env = os.environ.get("BROWSER_MATRIX_PROFILES", "")
    profiles = [p.strip() for p in profiles_env.split(",") if p.strip()] or None

    try:
        async with httpx.AsyncClient(timeout=600.0) as c:
            r = await c.post(
                f"{CONSENT_TESTER_URL}/scan-matrix",
                json={
                    "url": banner_url,
                    "timeout_per_phase": 10,
                    "categories": [],
                    "browser_profiles": profiles,
                },
            )
            if r.status_code != 200:
                logger.warning("browser-matrix scan HTTP %d", r.status_code)
                return
            data = r.json()
    except Exception as e:
        logger.warning("browser-matrix scan failed: %s", e)
        return

    state["browser_matrix"] = data.get("browser_matrix") or []
    state["browser_aggregate"] = data.get("aggregate") or {}
    state["browser_matrix_html"] = _render(
        state["browser_matrix"], state["browser_aggregate"],
    )
    logger.info(
        "browser-matrix: %d profiles, worst=%s@%s%%, best=%s@%s%%",
        len(state["browser_matrix"]),
        state["browser_aggregate"].get("worst_profile"),
        state["browser_aggregate"].get("worst_score"),
        state["browser_aggregate"].get("best_profile"),
        state["browser_aggregate"].get("best_score"),
    )


def _render(rows: list[dict], aggregate: dict) -> str:
    if not rows:
        return ""
    table_rows = []
    for r in rows:
        sev = ("fail" if r["score"] < 60
               else "warn" if r["score"] < 80 else "pass")
        color = ("#dc2626" if sev == "fail"
                 else "#f59e0b" if sev == "warn" else "#15803d")
        dims = r.get("dimensions") or {}
        dims_str = (
            f"PC {int(dims.get('pre_consent',0)*100)}% · "
            f"RR {int(dims.get('reject_respect',0)*100)}% · "
            f"BD {int(dims.get('banner_design',0)*100)}%"
        )
        table_rows.append(
            "<tr>"
            f"<td style='padding:6px 10px;border-bottom:1px solid #e5e7eb;'>"
            f"{h(r.get('label') or r.get('profile_id') or '—')}</td>"
            f"<td style='padding:6px 10px;border-bottom:1px solid #e5e7eb;"
            f"color:{color};font-weight:600;'>{r['score']}%</td>"
            f"<td style='padding:6px 10px;border-bottom:1px solid #e5e7eb;"
            f"color:#475569;font-size:12px;'>{dims_str}</td>"
            f"<td style='padding:6px 10px;border-bottom:1px solid #e5e7eb;"
            f"color:#475569;font-size:13px;'>{h(r.get('verbal','—'))}</td>"
            "</tr>"
        )
    worst = aggregate.get("worst_score", 0)
    sev_color = ("#dc2626" if worst < 60
                 else "#f59e0b" if worst < 80 else "#15803d")
    head = (
        f"<p style='margin:0 0 8px;font-size:13px;color:#475569;'>"
        f"<strong style='color:{sev_color};'>Worst-of {worst}%</strong> "
        f"(Profil <code>{aggregate.get('worst_profile','—')}</code>) — "
        f"Best-of {aggregate.get('best_score','—')}% "
        f"(<code>{aggregate.get('best_profile','—')}</code>). "
        "Aggregierter Score nach Worst-of-Regel: ein HIGH-Verstoß "
        "auf einem Browser kappt den Gesamt-Score.</p>"
    )
    return (
        "<div style='margin:24px 0;padding:16px;border-left:4px solid "
        f"{sev_color};background:#f8fafc;border-radius:4px;'>"
        "<h2 style='margin:0 0 8px;color:#1e293b;font-size:16px;'>"
        "🌐 Browser-Matrix · Consent-Robustness pro Engine"
        "</h2>"
        f"{head}"
        "<table style='width:100%;border-collapse:collapse;font-size:13px;"
        "margin-top:8px;background:#fff;'>"
        "<thead><tr style='background:#f1f5f9;'>"
        "<th style='text-align:left;padding:6px 10px;'>Browser-Profil</th>"
        "<th style='text-align:left;padding:6px 10px;'>Score</th>"
        "<th style='text-align:left;padding:6px 10px;'>Pre-Consent · "
        "Reject-Respekt · Banner-Design</th>"
        "<th style='text-align:left;padding:6px 10px;'>Bewertung</th>"
        "</tr></thead>"
        f"<tbody>{''.join(table_rows)}</tbody></table>"
        "</div>"
    )
