"""EmailService — Postmark client + dev-mode logging fallback."""

from __future__ import annotations

import logging
from unittest.mock import patch

import httpx
import pytest

from app.email import (
    EmailDeliveryError,
    LicenseEmail,
    LoggingEmailService,
    PostmarkEmailService,
    _render_html,
    _render_text,
    get_email_service,
)


def _msg() -> LicenseEmail:
    return LicenseEmail(
        to_name="Jane Doe",
        to_email="jane@example.com",
        tier="core",
        license_key="DT1-CORE-aaaa-bbbb",
        expires_at_iso="2027-05-14T01:00:00Z",
        blob="DTLIC2:placeholder",
    )


def test_render_text_contains_essentials():
    body = _render_text(_msg())
    assert "Jane Doe" in body
    assert "DTLIC2:placeholder" in body
    assert "DT1-CORE-aaaa-bbbb" in body
    assert "core" in body
    assert "2027-05-14" in body


def test_render_html_escapes_user_input():
    msg = LicenseEmail(
        to_name="<script>alert(1)</script>",
        to_email="x@y.com",
        tier="core",
        license_key="K",
        expires_at_iso="2030-01-01T00:00:00Z",
        blob="DTLIC2:x",
    )
    html = _render_html(msg)
    assert "<script>" not in html
    assert "&lt;script&gt;" in html


def test_logging_service_writes_to_log(caplog):
    caplog.set_level(logging.INFO)
    svc = LoggingEmailService()
    result = svc.send_license(_msg())
    assert result == "logged"
    log_text = "\n".join(r.message for r in caplog.records)
    assert "would send" in log_text
    assert "jane@example.com" in log_text
    assert "DTLIC2:placeholder" in log_text


def test_factory_returns_logging_when_no_token(monkeypatch):
    monkeypatch.delenv("POSTMARK_TOKEN", raising=False)
    monkeypatch.delenv("POSTMARK_TOKEN_FILE", raising=False)
    from app.config import get_settings
    get_settings.cache_clear()
    svc = get_email_service()
    assert isinstance(svc, LoggingEmailService)


def test_postmark_send_success():
    svc = PostmarkEmailService("test-token", sender="from@example.com")

    def handler(request: httpx.Request) -> httpx.Response:
        body = request.read().decode()
        assert "from@example.com" in body
        assert "jane@example.com" in body
        assert "DTLIC2:placeholder" in body
        return httpx.Response(200, json={"MessageID": "pm-12345"})

    transport = httpx.MockTransport(handler)
    _real_client = httpx.Client
    with patch("app.email.httpx.Client", lambda **kw: _real_client(transport=transport, **kw)):
        msg_id = svc.send_license(_msg())
    assert msg_id == "pm-12345"


def test_postmark_send_raises_on_failure():
    svc = PostmarkEmailService("test-token", sender="from@example.com")

    def handler(request: httpx.Request) -> httpx.Response:
        return httpx.Response(422, json={"Message": "Invalid sender"})

    transport = httpx.MockTransport(handler)
    _real_client = httpx.Client
    with patch("app.email.httpx.Client", lambda **kw: _real_client(transport=transport, **kw)):
        with pytest.raises(EmailDeliveryError, match="422"):
            svc.send_license(_msg())
