import asyncio

import app.safety.emergency as em


class FakeUser:
    id = "u1"
    display_name = "Anzeigename"

    def __init__(self, prefs):
        self.prefs = prefs


FULL_PREFS = {
    "full_name": "Frieda Schlüter",
    "street": "Hauptstraße 12",
    "postal_code": "24103",
    "city": "Kiel",
    "phone_mobile": "+4915100000000",
    "phone_landline": "+4943100000",
    "birth_date": "1940-05-01",
    "medical_notes": "Diabetes, Marcumar",
}
GEO = {"lat": 54.3233, "lon": 10.1394, "accuracy": 12.5, "ts": "2026-06-25T12:00:00Z"}
MAPS = "https://www.google.com/maps?q=54.3233,10.1394"


def test_profile_fallback_to_display_name():
    p = em._profile(FakeUser({}))
    assert p["name"] == "Anzeigename"
    assert p["address_short"] == ""


def test_profile_address_compose():
    p = em._profile(FakeUser(FULL_PREFS))
    assert p["name"] == "Frieda Schlüter"
    assert p["address_short"] == "Hauptstraße 12, 24103 Kiel"


def test_sms_text_has_name_address_and_maps_link():
    p = em._profile(FakeUser(FULL_PREFS))
    sms = em._emergency_texts(p, GEO)["sms"]
    assert "Frieda Schlüter" in sms
    assert "Hauptstraße 12, 24103 Kiel" in sms
    assert MAPS in sms


def test_call_text_has_no_url_or_coords():
    p = em._profile(FakeUser(FULL_PREFS))
    call = em._emergency_texts(p, GEO)["call"]
    assert "Wohnadresse: Hauptstraße 12, 24103 Kiel" in call
    assert "http" not in call and "54.3233" not in call
    assert "SMS und der E-Mail" in call


def test_email_body_full_dossier_with_geo():
    p = em._profile(FakeUser(FULL_PREFS))
    body = em._email_body(p, GEO)
    assert "Medizinische Hinweise: Diabetes, Marcumar" in body
    assert "Mobil: +4915100000000" in body
    assert f"Karte: {MAPS}" in body
    assert "ca. 12 m" in body  # round(12.5) -> 12


def test_email_body_geo_unavailable():
    body = em._email_body(em._profile(FakeUser(FULL_PREFS)), None)
    assert "nicht verfügbar" in body


def test_geo_fields_handles_dict_and_partial():
    assert em._geo_fields(None) is None
    assert em._geo_fields({"lat": 1.0}) is None  # lon fehlt -> None
    g = em._geo_fields({"lat": 1.0, "lon": 2.0})
    assert g["lat"] == 1.0 and g["accuracy"] is None


def test_webhook_payload_includes_geo_and_messages():
    user = FakeUser(FULL_PREFS)
    p = em._profile(user)
    payload = em._webhook_payload(user, "de", ["+49"], ["sms", "call"], p, GEO)
    assert payload["geo"]["lat"] == 54.3233
    assert MAPS in payload["message"]["sms"]
    assert payload["user"]["name"] == "Frieda Schlüter"


def test_record_manual_emergency_uses_profile(monkeypatch):
    captured = {}

    def fake_send_email(to, subject, body, cfg):
        captured.update(to=to, subject=subject, body=body)
        return True

    monkeypatch.setattr(em, "_send_email_sync", fake_send_email)
    monkeypatch.setattr(em.settings, "smtp_host", "mail.example.com")
    monkeypatch.setattr(em.settings, "emergency_contact_email", "kontakt@example.com")
    monkeypatch.setattr(em.settings, "emergency_webhook_url", "")  # nur E-Mail isolieren

    class DummyStore:
        def log_emergency(self, *a, **k):
            pass

    res = asyncio.run(
        em.record_manual_emergency(FakeUser(FULL_PREFS), DummyStore(), language="de", geo=GEO)
    )
    assert res["email_sent"] is True and res["webhook_sent"] is False
    assert "Frieda Schlüter" in captured["subject"]
    assert "Diabetes" in captured["body"]
    assert MAPS in captured["body"]


def test_sms_includes_phone():
    p = em._profile(FakeUser(FULL_PREFS))
    sms = em._emergency_texts(p, GEO)["sms"]
    assert "Tel: +4915100000000" in sms


def test_email_geo_error_shown():
    p = em._profile(FakeUser(FULL_PREFS))
    body = em._email_body(p, None, "code 2: POSITION_UNAVAILABLE", None)
    assert "nicht verfügbar" in body and "code 2" in body


def test_email_device_line_mobile_and_desktop():
    p = em._profile(FakeUser(FULL_PREFS))
    assert "Festgerät" in em._email_body(p, GEO, None, {"mobile": False, "platform": "Linux"})
    assert "Mobilgerät" in em._email_body(p, GEO, None, {"mobile": True, "platform": "Android"})
