"""Smoke tests for mail-render V2."""

from unittest.mock import MagicMock

from compliance.services.mail_render_v2._compose import compose_v2
from compliance.services.mail_render_v2._cookie_inventory import (
    build_cookie_inventory,
)
from compliance.services.mail_render_v2._style import (
    card, chip, kpi_row, page_close, page_open, section, table,
)


def _mock_check_result(label, doc_type, url, comp, corr, n_checks, n_fail):
    r = MagicMock()
    r.label = label
    r.doc_type = doc_type
    r.url = url
    r.completeness_pct = comp
    r.correctness_pct = corr
    r.error = ""
    r.scenario = "fix"
    checks = []
    for i in range(n_checks):
        c = MagicMock()
        c.id = f"mc-{i}"
        c.label = f"Check {i}"
        c.passed = i >= n_fail
        c.severity = "HIGH" if i < n_fail else "LOW"
        c.skipped = False
        c.hint = f"Hint {i}" if i < n_fail else ""
        c.regulation = "DSGVO"
        c.level = 2
        c.matched_text = ""
        checks.append(c)
    r.checks = checks
    return r


def _full_state():
    return {
        "check_id": "abc12345",
        "site_name": "Example AG",
        "domain": "example.de",
        "doc_count": 5,
        "results": [
            _mock_check_result("Impressum", "impressum",
                               "https://example.de/impressum", 95, 92, 10, 1),
            _mock_check_result("Datenschutzerklärung", "dse",
                               "https://example.de/dse", 80, 63, 20, 5),
        ],
        "total_findings": 6,
        "cmp_vendors": [
            {"name": "Google", "source": "table_crawled",
             "cookies": [
                 {"name": "_ga", "category": "Statistik",
                  "duration": "14 Monate"},
                 {"name": "_gid", "category": "Statistik",
                  "duration": "24h"},
             ]},
            {"name": "Meta", "source": "html_table",
             "cookies": [
                 {"name": "_fbp", "category": "Marketing",
                  "duration": "3 Monate"},
             ]},
        ],
        "banner_result": {
            "banner_detected": True,
            "banner_provider": "Cookiebot",
            "cookies_detailed": [
                {"name": "_ga", "domain": "example.de"},
                {"name": "_fbp", "domain": "facebook.net"},
                {"name": "undocumented_pixel", "domain": "tracker.com"},
            ],
            "banner_checks": {"violations": [{"id": "v1"}]},
        },
        "cookie_audit": {
            "declared_count": 3,
            "browser_count": 3,
            "undeclared_in_browser": [{"name": "undocumented_pixel"}],
            "compliant": [{"name": "_ga"}, {"name": "_fbp"}],
        },
        "scorecard": {"totals": {"pct": 72}},
        "retention_findings": [
            {"matches": False, "cookie_name": "_ga", "vendor_name": "Google",
             "severity": "HIGH", "severity_reason": "factually_wrong",
             "mismatch_type": "dsi_under_actual",
             "dsi_days": 180, "table_days": 420, "actual_days": 420,
             "diff_days": 240},
            {"matches": True, "cookie_name": "_fbp", "severity": None,
             "severity_reason": None},
        ],
        "retention_theme_summary": {
            "theme_id": "TH-RETENTION", "total": 2, "passed": 1,
            "failed": 1, "incomplete": 0, "pct": 50,
            "by_severity": {"HIGH": 1}, "by_mismatch_type": {},
            "top_fails": [],
        },
        "reachability_finding": {
            "check_id": "COOKIE-CONSENT-UX-001",
            "passed": False, "severity": "HIGH",
            "severity_reason": "missing",
            "notes": ["no consent-manager link in footer"],
            "reopen_anchor": None,
            "anchors_total": 0,
        },
        "cookie_evidence_slices": [{"idx": 0}, {"idx": 1}],
        "cookie_evidence_meta": {"url": "https://example.de/cookie"},
        "audit_quality_findings": [
            {"severity": "MEDIUM", "title": "Cookie-URL nicht erreichbar",
             "message": "Auto-Discovery hat keine Alternative gefunden."},
        ],
    }


class TestStyleHelpers:
    def test_section_wraps_with_title(self):
        out = section("My Section", "<p>body</p>")
        assert "My Section" in out
        assert "<p>body</p>" in out

    def test_chip_renders_text(self):
        out = chip("FAIL", "fail")
        assert "FAIL" in out

    def test_table_basic(self):
        out = table(["A", "B"], [["1", "2"], ["3", "4"]])
        assert "<thead>" in out
        assert ">1<" in out and ">4<" in out

    def test_kpi_row_4(self):
        out = kpi_row([
            {"label": "Score", "value": "92%", "sev": "pass"},
            {"label": "Findings", "value": "3"},
            {"label": "Docs", "value": "5/7"},
            {"label": "Vendors", "value": "12"},
        ])
        assert "Score" in out and "92%" in out

    def test_card_with_sev(self):
        out = card("inner", sev="warn")
        assert "inner" in out

    def test_page_wraps(self):
        head = page_open("Foo")
        tail = page_close("abc123", "deadbee")
        assert "Foo" not in head  # site_name not in open shell
        assert "abc123" in tail and "deadbee" in tail


class TestCookieInventory:
    def test_merge_declared_and_browser(self):
        st = _full_state()
        rows, summary = build_cookie_inventory(st)
        assert summary["total"] >= 3
        names = [r["name"].lower() for r in rows]
        assert "_ga" in names
        assert "undocumented_pixel" in names

    def test_status_undoc_for_browser_only(self):
        st = _full_state()
        rows, _ = build_cookie_inventory(st)
        undoc = next(r for r in rows
                     if r["name"].lower() == "undocumented_pixel")
        assert undoc["status_code"] == "UNDOC"
        assert undoc["status_sev"] == "fail"

    def test_status_ok_for_compliant(self):
        st = _full_state()
        rows, _ = build_cookie_inventory(st)
        ga = next(r for r in rows if r["name"].lower() == "_ga")
        assert ga["status_code"] == "OK"

    def test_empty_state(self):
        rows, summary = build_cookie_inventory({})
        assert rows == []
        assert summary["total"] == 0


class TestComposeV2:
    def test_full_render(self):
        st = _full_state()
        html = compose_v2(st)
        # Header
        assert "Example AG" in html
        assert "example.de" in html
        # KPIs
        assert "72%" in html
        # Critical
        assert "1. Kritische Befunde" in html
        # Per Doc
        assert "Impressum" in html
        assert "Datenschutzerklärung" in html
        # Per Theme
        assert "Cookie-Inventar" in html
        assert "UNDOC" in html
        # Reachability
        assert "Mobile Reachability" in html
        # Retention
        assert "TH-RETENTION" in html
        # Caveats
        assert "Cookie-URL nicht erreichbar" in html
        # Attachments
        assert "evidence-abc12345" in html

    def test_no_critical_when_clean(self):
        st = _full_state()
        st["results"] = []
        st["reachability_finding"] = {"passed": True, "severity": None,
                                      "notes": []}
        st["retention_findings"] = []
        html = compose_v2(st)
        assert "Keine HIGH/CRITICAL-Befunde" in html
