"""Tests for email service specification models."""

from __future__ import annotations

import pytest

from prisme.spec.email import EmailServiceConfig, EmailTemplateSpec


class TestEmailTemplateSpec:
    """Tests for EmailTemplateSpec."""

    def test_valid_template(self):
        """Valid template spec is created successfully."""
        tmpl = EmailTemplateSpec(
            name="order_confirmation",
            subject="Order #{order_id} confirmed",
            description="Sent when an order is placed",
            variables=["order_id", "customer_name", "total"],
        )
        assert tmpl.name == "order_confirmation"
        assert tmpl.subject == "Order #{order_id} confirmed"
        assert len(tmpl.variables) == 3

    def test_minimal_template(self):
        """Template with only required fields."""
        tmpl = EmailTemplateSpec(name="welcome", subject="Welcome!")
        assert tmpl.name == "welcome"
        assert tmpl.variables == []
        assert tmpl.description == ""

    def test_invalid_name_uppercase(self):
        """Template name with uppercase letters is rejected."""
        with pytest.raises(ValueError, match="snake_case"):
            EmailTemplateSpec(name="OrderConfirmation", subject="test")

    def test_invalid_name_starts_with_number(self):
        """Template name starting with number is rejected."""
        with pytest.raises(ValueError, match="snake_case"):
            EmailTemplateSpec(name="1_order", subject="test")

    def test_invalid_name_with_dashes(self):
        """Template name with dashes is rejected."""
        with pytest.raises(ValueError, match="snake_case"):
            EmailTemplateSpec(name="order-confirmation", subject="test")

    def test_extra_fields_forbidden(self):
        """Extra fields are rejected."""
        with pytest.raises(ValueError):
            EmailTemplateSpec(name="test", subject="test", unknown_field="value")


class TestEmailServiceConfig:
    """Tests for EmailServiceConfig."""

    def test_defaults(self):
        """Default config has email disabled."""
        config = EmailServiceConfig()
        assert config.enabled is False
        assert config.from_address == "noreply@madewithpris.me"
        assert config.resend_api_key_env == "RESEND_API_KEY"
        assert config.reply_to is None
        assert config.templates == []

    def test_enabled_with_templates(self):
        """Config with templates enabled."""
        config = EmailServiceConfig(
            enabled=True,
            from_address="MyApp <noreply@example.com>",
            reply_to="support@example.com",
            templates=[
                EmailTemplateSpec(
                    name="welcome",
                    subject="Welcome to {app_name}!",
                    variables=["user_name", "app_name"],
                ),
                EmailTemplateSpec(
                    name="order_shipped",
                    subject="Your order #{order_id} has shipped",
                    variables=["order_id", "tracking_url"],
                ),
            ],
        )
        assert config.enabled is True
        assert config.reply_to == "support@example.com"
        assert len(config.templates) == 2
        assert config.templates[0].name == "welcome"
        assert config.templates[1].name == "order_shipped"

    def test_duplicate_template_names_rejected(self):
        """Duplicate template names are rejected."""
        with pytest.raises(ValueError, match="Duplicate"):
            EmailServiceConfig(
                enabled=True,
                templates=[
                    EmailTemplateSpec(name="welcome", subject="Welcome"),
                    EmailTemplateSpec(name="welcome", subject="Welcome again"),
                ],
            )

    def test_custom_resend_env(self):
        """Custom Resend API key env variable."""
        config = EmailServiceConfig(
            enabled=True,
            resend_api_key_env="MY_RESEND_KEY",
        )
        assert config.resend_api_key_env == "MY_RESEND_KEY"

    def test_extra_fields_forbidden(self):
        """Extra fields are rejected."""
        with pytest.raises(ValueError):
            EmailServiceConfig(enabled=True, provider="sendgrid")
