"""Email service specification.

Defines general-purpose email configuration for Prism-generated applications.
Uses Resend API for sending transactional and business logic emails.
"""

from __future__ import annotations

from pydantic import BaseModel, Field, field_validator


class EmailTemplateSpec(BaseModel):
    """Defines a custom email template for the generated project.

    Each template generates a send function and an HTML template file.

    Example:
        ```python
        EmailTemplateSpec(
            name="order_confirmation",
            subject="Order #{order_id} confirmed",
            description="Sent when an order is confirmed",
            variables=["order_id", "customer_name", "total"],
        )
        ```
    """

    name: str = Field(
        ...,
        description="Template name in snake_case (e.g. 'order_confirmation')",
    )
    subject: str = Field(
        ...,
        description="Email subject line. Can include {variable} placeholders.",
    )
    description: str = Field(
        default="",
        description="Human-readable description of when this email is sent",
    )
    variables: list[str] = Field(
        default_factory=list,
        description="Variable names available in the template (e.g. ['user_name', 'order_id'])",
    )

    @field_validator("name")
    @classmethod
    def validate_name(cls, v: str) -> str:
        """Validate template name is snake_case."""
        import re

        if not re.match(r"^[a-z][a-z0-9_]*$", v):
            raise ValueError(
                f"Template name must be snake_case (lowercase letters, numbers, underscores): '{v}'"
            )
        return v

    model_config = {"extra": "forbid"}


class EmailServiceConfig(BaseModel):
    """General-purpose email service configuration.

    Enables transactional email sending for business logic beyond authentication.
    Uses Resend API as the email provider.

    Example:
        ```python
        from prisme.spec.email import EmailServiceConfig, EmailTemplateSpec

        email = 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_confirmation",
                    subject="Order #{order_id} confirmed",
                    variables=["order_id", "customer_name", "total"],
                ),
            ],
        )
        ```
    """

    enabled: bool = Field(
        default=False,
        description="Enable general-purpose email service generation",
    )
    from_address: str = Field(
        default="noreply@madewithpris.me",
        description="Default From address (e.g. 'MyApp <noreply@example.com>')",
    )
    resend_api_key_env: str = Field(
        default="RESEND_API_KEY",
        description="Environment variable name for Resend API key",
    )
    reply_to: str | None = Field(
        default=None,
        description="Default Reply-To address (optional)",
    )
    templates: list[EmailTemplateSpec] = Field(
        default_factory=list,
        description="Custom email templates to generate",
    )

    @field_validator("templates")
    @classmethod
    def validate_unique_template_names(cls, v: list[EmailTemplateSpec]) -> list[EmailTemplateSpec]:
        """Ensure template names are unique."""
        names = [t.name for t in v]
        duplicates = [n for n in names if names.count(n) > 1]
        if duplicates:
            raise ValueError(f"Duplicate email template names: {set(duplicates)}")
        return v

    model_config = {"extra": "forbid"}
