"""Tests for B13 Widerrufsbelehrung-Reachability-Check."""

from compliance.services.widerrufsbelehrung_reachability_check import (
    _detect_b2c_scope,
    check_widerrufsbelehrung_reachability,
)


def _state(widerruf_entry=None, home_text="", doc_entries=None,
           footer_text=""):
    entries = list(doc_entries or [])
    if widerruf_entry is not None:
        entries.append({"doc_type": "widerruf", **widerruf_entry})
    return {
        "doc_entries": entries,
        "home_text": home_text,
        "footer_text": footer_text,
    }


class TestDetectB2CScope:
    def test_strong_b2c_warenkorb(self):
        s = _state(home_text="Legen Sie das Produkt in den Warenkorb.")
        scope, hits = _detect_b2c_scope(s)
        assert scope == "b2c_strong"
        assert any("warenkorb" in h for h in hits)

    def test_b2b_only_overrides_b2c(self):
        s = _state(home_text="Wir verkaufen ausschließlich an Unternehmer. "
                             "Warenkorb für Großkunden.")
        scope, _ = _detect_b2c_scope(s)
        assert scope == "b2b_only"

    def test_weak_signals_two_promote_to_likely(self):
        s = _state(home_text="Unser Shop bietet Wallbox-Produkte mit "
                             "Rechnung zur Bestellung.")
        scope, _ = _detect_b2c_scope(s)
        assert scope == "b2c_likely"

    def test_single_weak_signal_stays_unknown(self):
        s = _state(home_text="Wir bieten einen Shop.")
        scope, _ = _detect_b2c_scope(s)
        assert scope == "unknown"

    def test_versicherung_combo_promotes_to_likely(self):
        s = _state(home_text="Reiseversicherung jetzt online "
                             "abschließen. Tarifrechner verfügbar.")
        scope, _ = _detect_b2c_scope(s)
        assert scope == "b2c_likely"

    def test_buchung_combo_promotes_to_likely(self):
        s = _state(home_text="Flug buchen oder Hotel reservieren.")
        scope, _ = _detect_b2c_scope(s)
        assert scope == "b2c_likely"

    def test_empty_state(self):
        s = _state()
        scope, _ = _detect_b2c_scope(s)
        assert scope == "unknown"


class TestCheck:
    def test_no_widerruf_entry_no_finding(self):
        out = check_widerrufsbelehrung_reachability(_state())
        assert out == []

    def test_widerruf_reachable_no_finding(self):
        out = check_widerrufsbelehrung_reachability(_state(
            widerruf_entry={
                "url": "https://shop.de/widerruf",
                "text": "Belehrung " * 100,
                "discovery_attempted": True,
            },
            home_text="Warenkorb / zur Kasse.",
        ))
        assert out == []

    def test_unreachable_plus_b2c_strong_high_finding(self):
        out = check_widerrufsbelehrung_reachability(_state(
            widerruf_entry={
                "url": "", "text": "",
                "discovery_attempted": True,
                "rejected_url": "https://shop.de/widerruf",
            },
            home_text="In den Warenkorb. Lieferzeit 2 Tage. Preis inkl. MwSt.",
        ))
        assert len(out) == 1
        f = out[0]
        assert f["check_id"] == "WIDERRUF-REACH-001"
        assert f["severity"] == "HIGH"
        assert f["b2c_scope"] == "b2c_strong"
        assert "Art. 246a" in f["norm"]
        assert "shop.de/widerruf" in f["evidence"]

    def test_unreachable_plus_b2c_likely_medium(self):
        out = check_widerrufsbelehrung_reachability(_state(
            widerruf_entry={
                "url": "", "text": "",
                "discovery_attempted": True,
            },
            home_text="Shop bietet Wallbox und Tarif buchen.",
        ))
        assert len(out) == 1
        assert out[0]["severity"] == "MEDIUM"
        assert out[0]["b2c_scope"] == "b2c_likely"

    def test_unreachable_plus_b2b_only_no_finding(self):
        out = check_widerrufsbelehrung_reachability(_state(
            widerruf_entry={
                "url": "", "text": "",
                "discovery_attempted": True,
            },
            home_text="B2B only — kein Verkauf an Verbraucher.",
        ))
        assert out == []

    def test_unreachable_plus_unknown_scope_no_finding(self):
        # Pure agency / B2B-services without clear shop signals — silent.
        out = check_widerrufsbelehrung_reachability(_state(
            widerruf_entry={
                "url": "", "text": "",
                "discovery_attempted": True,
            },
            home_text="Wir sind eine Beratungsagentur für Mittelstand.",
        ))
        assert out == []

    def test_discovery_not_attempted_no_finding(self):
        # Avoid false positives when discovery had no homepage to crawl.
        out = check_widerrufsbelehrung_reachability(_state(
            widerruf_entry={
                "url": "", "text": "",
                "discovery_attempted": False,
            },
            home_text="In den Warenkorb. Preis inkl. MwSt.",
        ))
        assert out == []

    def test_footer_widerruf_link_suppresses_finding(self):
        out = check_widerrufsbelehrung_reachability(_state(
            widerruf_entry={
                "url": "", "text": "",
                "discovery_attempted": True,
            },
            home_text="Warenkorb. Lieferzeit. Preis inkl. MwSt.",
            footer_text='<a href="/widerruf">Widerruf</a>',
        ))
        assert out == []
