"""8B freeze: existing Email Template catalog/overlay vs email.send / Forms boundaries.

Does not implement a template engine, table, or send verb. Does not advance the tracker.
"""
from __future__ import annotations

import pytest
from pydantic import ValidationError

from src.domain.codegen.email_templates_manifest import (
    EMAIL_TEMPLATE_CATALOG,
    EmailTemplateDeclaration,
    EmailTemplatesManifest,
    validate_manifest,
)
from src.domain.connectors.invoke_capabilities import CAPABILITY_CONVERSION_PATTERN
from src.domain.connectors.schemas import InvokeEmailSendRequest
from src.domain.forms.email import (
    FORBIDDEN_EMAIL_CONSTANT_KEYS,
    FORMS_EMAIL_COMPOSITION,
    GENERIC_EMAIL_ACTION,
)


CLOSED_KEYS = (
    "auth.verify_email",
    "auth.otp_request",
    "auth.magic_link",
    "auth.password_reset",
    "auth.invite",
    "contact_capture.admin_notify",
    "contact_capture.confirmation",
)


def test_catalog_is_the_closed_seven_keys() -> None:
    assert tuple(EMAIL_TEMPLATE_CATALOG) == CLOSED_KEYS
    for key in ("auth.verify_email", "auth.otp_request", "auth.magic_link", "auth.password_reset", "auth.invite"):
        assert EMAIL_TEMPLATE_CATALOG[key]["optional"] is False
        assert EMAIL_TEMPLATE_CATALOG[key]["protected_placeholders"]
    assert EMAIL_TEMPLATE_CATALOG["contact_capture.admin_notify"]["optional"] is True
    assert EMAIL_TEMPLATE_CATALOG["contact_capture.admin_notify"]["protected_placeholders"] == []
    assert EMAIL_TEMPLATE_CATALOG["contact_capture.confirmation"]["optional"] is True


def test_unknown_template_key_rejected() -> None:
    with pytest.raises(ValidationError, match="Unknown template_key"):
        EmailTemplateDeclaration(
            template_key="customer.welcome",
            subject="Hi",
            text_body="Hello",
        )


def test_protected_placeholder_required_on_override_source() -> None:
    with pytest.raises(ValidationError, match="action_url"):
        EmailTemplateDeclaration(
            template_key="auth.verify_email",
            subject="Verify",
            text_body="Please verify your email.",
        )
    ok = EmailTemplateDeclaration(
        template_key="auth.verify_email",
        subject="Verify",
        text_body="Verify: {{action_url}}",
        html_body="<p>{{action_url}}</p>",
    )
    assert ok.template_key == "auth.verify_email"


def test_overlay_forbids_delivery_fields() -> None:
    with pytest.raises(ValidationError):
        EmailTemplateDeclaration.model_validate(
            {
                "template_key": "contact_capture.confirmation",
                "subject": "Thanks",
                "text_body": "Hi",
                "reply_to": "a@b.com",
            }
        )
    with pytest.raises(ValidationError):
        EmailTemplateDeclaration.model_validate(
            {
                "template_key": "contact_capture.confirmation",
                "subject": "Thanks",
                "text_body": "Hi",
                "from": "noreply@example.com",
            }
        )


def test_duplicate_keys_rejected_and_empty_manifest_ok() -> None:
    with pytest.raises(ValidationError, match="Duplicate"):
        EmailTemplatesManifest.model_validate(
            {
                "version": 1,
                "templates": [
                    {
                        "template_key": "contact_capture.confirmation",
                        "subject": "A",
                        "text_body": "A",
                    },
                    {
                        "template_key": "contact_capture.confirmation",
                        "subject": "B",
                        "text_body": "B",
                    },
                ],
            }
        )
    dumped = validate_manifest({"version": 1, "templates": []})
    assert dumped["templates"] == []


def test_email_send_payload_has_no_template_reference() -> None:
    fields = set(InvokeEmailSendRequest.model_fields)
    assert fields == {"to", "subject", "text", "html", "reply_to", "idempotency_key"}
    assert "template_key" not in fields
    assert "template" not in fields
    InvokeEmailSendRequest(to="ada@example.com", subject="S", text="T")


def test_forms_email_composition_unchanged() -> None:
    assert GENERIC_EMAIL_ACTION == "email.send"
    assert FORMS_EMAIL_COMPOSITION["email_templates"] is False
    assert FORMS_EMAIL_COMPOSITION["interpolation"] is False
    assert "template_key" in FORBIDDEN_EMAIL_CONSTANT_KEYS
    assert "template_id" in FORBIDDEN_EMAIL_CONSTANT_KEYS


def test_program_tracker_not_advanced_by_8b() -> None:
    assert CAPABILITY_CONVERSION_PATTERN["phase_7_status"] == "complete"
    assert CAPABILITY_CONVERSION_PATTERN["forms_domain_status"] == "complete"
    assert CAPABILITY_CONVERSION_PATTERN["next_program_slice"] == "9_app_block_modernization"
    assert CAPABILITY_CONVERSION_PATTERN["next_candidates"] == ("email.templates",)
    assert "email.template.send" not in CAPABILITY_CONVERSION_PATTERN.get("templates", {})
