"""Canonical semantic email catalog.

This is a content contract, not an HTML template store and not a capability
registry. Capability admission still comes from Feature Packs/App Blocks and
the existing runtime contracts; this catalog only describes presentation when
an admitted operation emits a message.
"""
from __future__ import annotations

from dataclasses import dataclass
from typing import Literal

from src.domain.composition_recipes.schemas import CompositionRecipe

EmailArchetype = Literal[
    "action",
    "confirmation",
    "status_update",
    "reminder",
    "notification",
    "receipt",
    "summary",
    "security",
]


@dataclass(frozen=True)
class EmailProfile:
    id: str
    tone: str = "professional"
    density: str = "comfortable"
    branding: str = "application"
    detail_layout: str = "structured"


@dataclass(frozen=True)
class EmailTemplateDefinition:
    id: str
    version: int
    semantic_event: str
    archetype: EmailArchetype
    audience: str
    required_variables: tuple[str, ...] = ()
    optional_variables: tuple[str, ...] = ()
    security_policy: str | None = None
    default_profile: str = "neutral"

    @property
    def version_id(self) -> str:
        return f"{self.id}.v{self.version}"


EMAIL_ARCHETYPES: tuple[EmailArchetype, ...] = (
    "action", "confirmation", "status_update", "reminder",
    "notification", "receipt", "summary", "security",
)

EMAIL_PROFILES: dict[str, EmailProfile] = {
    "neutral": EmailProfile("neutral"),
    "hospitality.standard": EmailProfile("hospitality.standard", density="compact"),
    "appointment.standard": EmailProfile("appointment.standard", density="compact"),
    "commerce.standard": EmailProfile("commerce.standard", density="compact"),
    "professional.standard": EmailProfile("professional.standard"),
}


def _definition(
    id: str,
    semantic_event: str,
    archetype: EmailArchetype,
    audience: str,
    required_variables: tuple[str, ...] = (),
    optional_variables: tuple[str, ...] = (),
    security_policy: str | None = None,
    default_profile: str = "neutral",
) -> EmailTemplateDefinition:
    return EmailTemplateDefinition(
        id=id,
        version=1,
        semantic_event=semantic_event,
        archetype=archetype,
        audience=audience,
        required_variables=required_variables,
        optional_variables=optional_variables,
        security_policy=security_policy,
        default_profile=default_profile,
    )


# Only currently admitted/emitted families are listed. Future booking,
# commerce, CRM, and workflow entries must be added with their capability
# contract, not merely by adding a row here.
EMAIL_TEMPLATE_CATALOG: dict[str, EmailTemplateDefinition] = {
    "auth.verify_email": _definition("auth.verify_email", "auth.verify_email", "security", "user", ("action_url",), ("app_name",), security_policy="verification_contract"),
    "auth.otp_request": _definition("auth.otp_request", "auth.otp_request", "security", "user", ("code",), ("app_name",), security_policy="otp_contract"),
    "auth.magic_link": _definition("auth.magic_link", "auth.magic_link", "action", "user", ("action_url",), ("app_name",), security_policy="magic_link_contract"),
    "auth.password_reset": _definition("auth.password_reset", "auth.password_reset", "security", "user", ("action_url",), ("app_name",), security_policy="password_reset_contract"),
    "auth.invite": _definition("auth.invite", "auth.invite", "action", "user", ("action_url",), ("app_name",)),
    "contact_capture.admin_notify": _definition("contact_capture.admin_notify", "contact_capture.received", "notification", "staff", optional_variables=("name", "email", "message")),
    "contact_capture.confirmation": _definition("contact_capture.confirmation", "contact_capture.received", "confirmation", "customer", optional_variables=("name",)),
    "billing.invoice_paid": _definition("billing.invoice_paid", "billing.invoice_paid", "receipt", "workspace_member", optional_variables=("invoice_url", "amount")),
    "billing.payment_failed": _definition("billing.payment_failed", "billing.payment_failed", "status_update", "workspace_member", optional_variables=("invoice_url",)),
    "billing.subscription_canceled": _definition("billing.subscription_canceled", "billing.subscription_canceled", "status_update", "workspace_member", optional_variables=("plan", "period_end")),
    "billing.wallet_threshold": _definition("billing.wallet_threshold", "billing.wallet_threshold", "notification", "workspace_member", optional_variables=("wallet", "percent", "credits")),
    "billing.usage_topup_confirmation": _definition("billing.usage_topup_confirmation", "billing.usage_topup_confirmation", "receipt", "workspace_member", optional_variables=("package", "units", "amount")),
    "workspace.invitation": _definition("workspace.invitation", "workspace.invitation", "action", "invitee", ("action_url", "workspace_name")),
    "billing.delegation_request": _definition("billing.delegation_request", "billing.delegation_request", "notification", "workspace_owner", ("action_url", "workspace_name")),
}


def get_email_template_definition(template_id: str) -> EmailTemplateDefinition:
    try:
        return EMAIL_TEMPLATE_CATALOG[template_id]
    except KeyError as exc:
        raise ValueError(f"unknown canonical email template: {template_id}") from exc


def resolve_email_profile(recipe: CompositionRecipe | None) -> EmailProfile:
    """Resolve recipe presentation defaults without admitting any capability."""
    requested = recipe.presentation.email_profile if recipe else None
    return EMAIL_PROFILES.get(requested or "neutral", EMAIL_PROFILES["neutral"])
