import emergency_bridge.main as bridge
import seven_send.client as sc
from fastapi.testclient import TestClient

client = TestClient(bridge.app)

PAYLOAD = {
    "event": "emergency",
    "category": "manual",
    "channels": ["sms", "call"],
    "phones": ["+4915112345678"],
    "message": {"sms": "NOTRUF: Test", "call": "Achtung. Test & <Notfall>."},
}


class FakeResp:
    status_code = 200
    text = '{"success":"100"}'

    def json(self):
        return {"success": "100", "messages": [{"success": True}]}


def _fake_seven(monkeypatch, capture):
    """Mockt den seven.io-HTTP-Aufruf im seven_send-Client (eine Stelle für alles)."""
    def fake_post(url, data=None, headers=None, timeout=None):
        capture.append({"url": url, "data": data, "headers": headers})
        return FakeResp()

    monkeypatch.setattr(sc.httpx, "post", fake_post)


def test_health():
    r = client.get("/health")
    assert r.status_code == 200
    assert r.json()["status"] == "ok"


def test_notruf_sends_sms_and_voice(monkeypatch):
    monkeypatch.setenv("SEVENIO_API_KEY", "k")
    monkeypatch.delenv("BRIDGE_TOKEN", raising=False)
    cap = []
    _fake_seven(monkeypatch, cap)

    r = client.post("/notruf", json=PAYLOAD)
    assert r.status_code == 200
    assert r.json()["any_sent"] is True
    assert len(cap) == 2  # eine SMS + ein Anruf

    sms = next(c for c in cap if c["url"].endswith("/sms"))
    voice = next(c for c in cap if c["url"].endswith("/voice"))
    assert sms["headers"]["X-Api-Key"] == "k"
    assert sms["data"]["to"] == "+4915112345678"
    assert sms["data"]["text"] == "NOTRUF: Test"
    # Anruf-Text wird von seven_send als SSML verpackt und XML-escaped
    assert "<speak>" in voice["data"]["text"]
    assert "&amp;" in voice["data"]["text"]
    assert "&lt;Notfall&gt;" in voice["data"]["text"]


def test_notruf_rejects_bad_token(monkeypatch):
    monkeypatch.setenv("BRIDGE_TOKEN", "secret")
    r = client.post("/notruf", json=PAYLOAD, headers={"Authorization": "Bearer wrong"})
    assert r.status_code == 401


def test_notruf_accepts_good_token(monkeypatch):
    monkeypatch.setenv("BRIDGE_TOKEN", "secret")
    monkeypatch.setenv("SEVENIO_API_KEY", "k")
    _fake_seven(monkeypatch, [])
    r = client.post("/notruf", json=PAYLOAD, headers={"Authorization": "Bearer secret"})
    assert r.status_code == 200


def test_notruf_respects_channels(monkeypatch):
    monkeypatch.setenv("SEVENIO_API_KEY", "k")
    monkeypatch.delenv("BRIDGE_TOKEN", raising=False)
    cap = []
    _fake_seven(monkeypatch, cap)
    r = client.post("/notruf", json={**PAYLOAD, "channels": ["sms"]})
    assert r.status_code == 200
    assert len(cap) == 1
    assert cap[0]["url"].endswith("/sms")


def test_notruf_without_api_key(monkeypatch):
    monkeypatch.delenv("SEVENIO_API_KEY", raising=False)
    monkeypatch.delenv("BRIDGE_TOKEN", raising=False)

    def boom(*a, **k):  # ohne Key darf kein seven.io-Aufruf passieren
        raise AssertionError("kein Versand ohne API-Key")

    monkeypatch.setattr(sc.httpx, "post", boom)
    r = client.post("/notruf", json=PAYLOAD)
    assert r.status_code == 200
    body = r.json()
    assert body["any_sent"] is False
    assert all("nicht gesetzt" in res["info"] for res in body["results"])
