"""Email transport factory and SES adapter."""
from types import SimpleNamespace

import pytest

from src.config import Settings
from src.integrations.email_provider import (
    MailgunProvider,
    ResendProvider,
    SesProvider,
    cloud_email_from_header,
    cloud_email_platform_footer,
    cloud_email_transport_configured,
    email_transport_configured,
    get_email_provider,
    normalized_cloud_email_provider,
)


def test_email_transport_configured_resend_requires_key():
    unset = Settings(email_provider="resend", resend_api_key="")
    ready = Settings(email_provider="resend", resend_api_key="re_test")
    assert email_transport_configured(unset) is False
    assert email_transport_configured(ready) is True


def test_email_transport_configured_ses_does_not_need_resend():
    settings = Settings(
        email_provider="ses",
        resend_api_key="",
        mailgun_api_key="",
        from_email="noreply@p2hs.app",
    )
    assert email_transport_configured(settings) is True


def test_email_transport_configured_mailgun_needs_domain():
    missing_domain = Settings(email_provider="mailgun", mailgun_api_key="key", mailgun_domain="")
    ready = Settings(
        email_provider="mailgun",
        mailgun_api_key="key",
        mailgun_domain="mg.example.com",
    )
    assert email_transport_configured(missing_domain) is False
    assert email_transport_configured(ready) is True


def test_get_email_provider_selects_ses(monkeypatch):
    monkeypatch.setattr(
        "src.integrations.email_provider.get_settings",
        lambda: SimpleNamespace(
            email_provider="ses",
            from_name="P2HS",
            from_email="noreply@p2hs.app",
            ses_region="eu-west-1",
            ses_access_key_id="",
            ses_secret_access_key="",
            ses_configuration_set="",
        ),
    )
    assert isinstance(get_email_provider(), SesProvider)


def test_get_email_provider_defaults_to_resend(monkeypatch):
    monkeypatch.setattr(
        "src.integrations.email_provider.get_settings",
        lambda: SimpleNamespace(
            email_provider="resend",
            from_name="P2HS",
            from_email="noreply@p2hs.app",
            resend_api_key="",
        ),
    )
    assert isinstance(get_email_provider(), ResendProvider)


def test_get_email_provider_selects_mailgun(monkeypatch):
    monkeypatch.setattr(
        "src.integrations.email_provider.get_settings",
        lambda: SimpleNamespace(
            email_provider="mailgun",
            from_name="P2HS",
            from_email="noreply@p2hs.app",
            mailgun_api_key="key",
            mailgun_domain="mg.example.com",
        ),
    )
    assert isinstance(get_email_provider(), MailgunProvider)


@pytest.mark.asyncio
async def test_ses_provider_sends_via_injected_client(monkeypatch):
    captured = {}

    class FakeClient:
        def send_email(self, **kwargs):
            captured.update(kwargs)
            return {"MessageId": "ses-123"}

    monkeypatch.setattr(
        "src.integrations.email_provider.get_settings",
        lambda: SimpleNamespace(
            from_name="P2HS",
            from_email="noreply@p2hs.app",
            ses_region="us-east-1",
            ses_access_key_id="AKIATEST",
            ses_secret_access_key="secret",
            ses_configuration_set="auth-mail",
        ),
    )

    provider = SesProvider(client_factory=lambda **kw: FakeClient())
    result = await provider.send(
        "user@example.com",
        "Sign in",
        "<p>Hi</p>",
        text="Hi",
        reply_to="support@p2hs.com",
    )

    assert result.success is True
    assert result.message_id == "ses-123"
    assert captured["Destination"]["ToAddresses"] == ["user@example.com"]
    assert captured["ReplyToAddresses"] == ["support@p2hs.com"]
    assert captured["ConfigurationSetName"] == "auth-mail"
    assert captured["Message"]["Body"]["Text"]["Data"] == "Hi"
    assert "P2HS" in captured["Source"]
    assert "noreply@p2hs.app" in captured["Source"]


@pytest.mark.asyncio
async def test_ses_provider_omits_empty_credentials_for_iam(monkeypatch):
    seen_kwargs = {}

    class FakeClient:
        def send_email(self, **kwargs):
            return {"MessageId": "ses-iam"}

    def factory(**kwargs):
        seen_kwargs.update(kwargs)
        return FakeClient()

    monkeypatch.setattr(
        "src.integrations.email_provider.get_settings",
        lambda: SimpleNamespace(
            from_name="P2HS",
            from_email="noreply@p2hs.app",
            ses_region="us-east-1",
            ses_access_key_id="",
            ses_secret_access_key="",
            ses_configuration_set="",
        ),
    )

    provider = SesProvider(client_factory=factory)
    result = await provider.send("user@example.com", "Hello", "<p>Hi</p>")

    assert result.success is True
    assert seen_kwargs == {"region_name": "us-east-1"}


def test_ses_settings_accept_aws_aliases(monkeypatch):
    for key in (
        "SES_REGION",
        "AWS_REGION",
        "SES_ACCESS_KEY_ID",
        "AWS_ACCESS_KEY_ID",
        "SES_SECRET_ACCESS_KEY",
        "AWS_SECRET_ACCESS_KEY",
    ):
        monkeypatch.delenv(key, raising=False)
    monkeypatch.setenv("AWS_REGION", "eu-central-1")
    monkeypatch.setenv("AWS_ACCESS_KEY_ID", "AKIAAWS")
    monkeypatch.setenv("AWS_SECRET_ACCESS_KEY", "aws-secret")
    settings = Settings(_env_file=None)
    assert settings.ses_region == "eu-central-1"
    assert settings.ses_access_key_id == "AKIAAWS"
    assert settings.ses_secret_access_key == "aws-secret"


def test_cloud_email_is_independent_of_core_email_provider():
    core_only = Settings(
        _env_file=None,
        email_provider="resend",
        resend_api_key="re_core",
        from_email="noreply@p2hs.app",
        cloud_email_provider="ses",
        cloud_email_from="",
        cloud_resend_api_key="",
        cloud_ses_access_key_id="",
        cloud_ses_secret_access_key="",
    )
    assert email_transport_configured(core_only) is True
    assert cloud_email_transport_configured(core_only) is False

    cloud_ready = Settings(
        _env_file=None,
        email_provider="resend",
        resend_api_key="",
        cloud_email_provider="resend",
        cloud_email_from="apps@p2hs.app",
        cloud_resend_api_key="re_cloud",
    )
    assert email_transport_configured(cloud_ready) is False
    assert cloud_email_transport_configured(cloud_ready) is True
    assert normalized_cloud_email_provider(cloud_ready) == "resend"


def test_cloud_email_ses_requires_explicit_keys():
    missing_keys = Settings(
        _env_file=None,
        cloud_email_provider="ses",
        cloud_email_from="apps@p2hs.app",
        cloud_ses_access_key_id="",
        cloud_ses_secret_access_key="",
    )
    ready = Settings(
        _env_file=None,
        cloud_email_provider="ses",
        cloud_email_from="apps@p2hs.app",
        cloud_ses_access_key_id="AKIACLOUD",
        cloud_ses_secret_access_key="cloud-secret",
    )
    assert cloud_email_transport_configured(missing_keys) is False
    assert cloud_email_transport_configured(ready) is True


def test_cloud_email_infers_ses_when_resend_default_has_no_key():
    settings = Settings(
        _env_file=None,
        cloud_email_provider="resend",
        cloud_email_from="apps@p2hs.app",
        cloud_email_from_name="P2HS Apps",
        cloud_resend_api_key="",
        cloud_ses_access_key_id="AKIACLOUD",
        cloud_ses_secret_access_key="cloud-secret",
    )
    assert normalized_cloud_email_provider(settings) == "ses"
    assert cloud_email_transport_configured(settings) is True


def test_cloud_email_mailgun_needs_domain():
    missing = Settings(
        _env_file=None,
        cloud_email_provider="mailgun",
        cloud_email_from="apps@p2hs.app",
        cloud_mailgun_api_key="key",
        cloud_mailgun_domain="",
        mailgun_api_key="core-key",
        mailgun_domain="mg.core.example",
    )
    ready = Settings(
        _env_file=None,
        cloud_email_provider="mailgun",
        cloud_email_from="apps@p2hs.app",
        cloud_mailgun_api_key="key",
        cloud_mailgun_domain="mg.apps.example",
    )
    assert cloud_email_transport_configured(missing) is False
    assert cloud_email_transport_configured(ready) is True


def test_cloud_email_from_header_prefers_project_name():
    from email.utils import parseaddr

    settings = Settings(
        _env_file=None,
        cloud_email_from="noreply@p2hsapp.com",
        cloud_email_from_name="P2HS.com",
    )
    fallback_name, fallback_addr = parseaddr(cloud_email_from_header(settings))
    assert fallback_name == "P2HS.com"
    assert fallback_addr == "noreply@p2hsapp.com"
    project_name, project_addr = parseaddr(
        cloud_email_from_header(settings, display_name="RF Consultant")
    )
    assert project_name == "RF Consultant"
    assert project_addr == "noreply@p2hsapp.com"


def test_cloud_email_platform_footer_links_home_url():
    settings = Settings(_env_file=None, home_url="https://p2hs.com")
    text, markup = cloud_email_platform_footer(settings)
    assert text == "Sent securely via P2HS"
    assert "Want to build your own site?" not in text
    assert "https://p2hs.com" not in markup
