"""7J Forms email composition: email.send only, no templates."""
from __future__ import annotations

from datetime import UTC, datetime
from pathlib import Path

from src.domain.connectors.invoke_capabilities import (
    CAPABILITY_CONVERSION_PATTERN,
    FORMS_FAMILY_PLAN,
    INVOKE_CAPABILITIES,
)
from src.domain.forms.actions import (
    FormCapabilityInvokeResult,
    FormPostSubmitAction,
    FormPostSubmitContext,
    FormPostSubmitPlan,
    RecordingCapabilityInvoker,
    action_idempotency_key,
    contact_compatible_plan,
    execute_post_submit_actions,
    validate_post_submit_plan,
)
from src.domain.forms.canonical import (
    FormDefinition,
    FormField,
    FormFileRef,
    FormSubmission,
    contact_block_compatible_definition,
)
from src.domain.forms.email import (
    FORMS_EMAIL_COMPOSITION,
    GENERIC_EMAIL_ACTION,
    INTERPOLATION,
    NO_RECIPIENT_CODE,
    build_email_send_payload,
    contact_legacy_notification_payload,
    email_send_action,
    validate_email_mapping,
)
from src.domain.forms.persistence import (
    FormPersistenceContext,
    FormPersistenceError,
    InMemoryFormSubmissionStore,
    get_form_submission,
)
from src.domain.forms.runtime import accept_form_submission

_FIXED_AT = datetime(2026, 9, 13, 21, 30, tzinfo=UTC)
_FSB_A = "fsb_" + ("a" * 32)
_FSB_B = "fsb_" + ("b" * 32)
_FILE_1 = "file_" + ("1" * 32)
_CTX = FormPostSubmitContext(project_id="prj_a")


class BoomStore:
    def persist(self, *args, **kwargs):
        raise FormPersistenceError("submission_persistence_failed")

    def get(self, *args, **kwargs):
        return None


def _accept(definition, raw, submission_id=_FSB_A):
    result = accept_form_submission(
        definition,
        raw,
        clock=lambda: _FIXED_AT,
        submission_id_factory=lambda: submission_id,
    )
    assert result.accepted is True
    return result.submission


def _email_fields(**extra: bool) -> FormDefinition:
    fields = [
        FormField(key="email", type="email", required=False),
        FormField(key="message", type="textarea", required=False),
        FormField(key="note", type="text", required=False),
        FormField(key="opt_in", type="checkbox", required=False),
        FormField(key="budget", type="number", required=False),
    ]
    if extra.get("file"):
        fields.append(FormField(key="resume", type="file", required=False))
    return FormDefinition(key="lead", fields=fields)


def test_7j_email_composition_frozen() -> None:
    assert FORMS_EMAIL_COMPOSITION["status"] == "frozen"
    assert FORMS_EMAIL_COMPOSITION["generic_action"] == "email.send"
    assert FORMS_EMAIL_COMPOSITION["email_templates"] is False
    assert FORMS_EMAIL_COMPOSITION["interpolation"] is False
    assert INTERPOLATION is False
    assert FORMS_EMAIL_COMPOSITION["no_recipient"] == "email_recipient_missing"
    assert FORMS_EMAIL_COMPOSITION["attachments"] is False
    assert FORMS_EMAIL_COMPOSITION["sender_in_forms"] is False
    assert FORMS_EMAIL_COMPOSITION["resolver_in_forms"] is False
    assert FORMS_EMAIL_COMPOSITION["legacy_contact_formatter"] == (
        "compatibility_helper_not_generic_renderer"
    )
    assert "form.email.send" not in INVOKE_CAPABILITIES
    assert GENERIC_EMAIL_ACTION in INVOKE_CAPABILITIES
    assert CAPABILITY_CONVERSION_PATTERN["phase_7_status"] == "complete"
    assert CAPABILITY_CONVERSION_PATTERN["next_program_slice"] == (
        "9_app_block_modernization"
    )
    assert CAPABILITY_CONVERSION_PATTERN["opened_families"]["forms.*"] == (
        "composition_integration"
    )
    assert FORMS_FAMILY_PLAN["status"] == "complete"
    assert FORMS_FAMILY_PLAN["email_composition_frozen"] is True
    assert FORMS_FAMILY_PLAN["slices"][9] == "7j_email_composition"
    assert FORMS_FAMILY_PLAN["next_slice"] == "9_app_block_modernization"
    assert "email_status" not in FormSubmission.model_fields
    assert "email_message_id" not in FormSubmission.model_fields
    source = Path("src/domain/forms/email.py").read_text(encoding="utf-8").lower()
    for token in ("resend", "mailgun", "ses", "smtp", "emailtemplate", "mjml"):
        assert token not in source


def test_form_email_maps_to_canonical_email_send() -> None:
    definition = _email_fields()
    accepted = _accept(
        definition,
        {"email": "Jane@Example.COM", "message": "Hello"},
    )
    invoker = RecordingCapabilityInvoker()
    result = execute_post_submit_actions(
        accepted,
        FormPostSubmitPlan(actions=(email_send_action(),)),
        context=_CTX,
        invoker=invoker,
        definition=definition,
    )
    assert result.plan_error is None
    assert result.actions[0].status == "succeeded"
    assert invoker.calls[0]["capability"] == "email.send"
    assert invoker.calls[0]["payload"] == {
        "to": "Jane@Example.COM",
        "text": "Hello",
        "subject": "Contact received",
    }
    assert "from" not in invoker.calls[0]["payload"]
    assert "template_id" not in invoker.calls[0]["payload"]


def test_missing_mapped_recipient_skips_without_invoke() -> None:
    definition = _email_fields()
    accepted = _accept(definition, {"message": "Hello"})
    invoker = RecordingCapabilityInvoker()
    result = execute_post_submit_actions(
        accepted,
        FormPostSubmitPlan(actions=(email_send_action(),)),
        context=_CTX,
        invoker=invoker,
        definition=definition,
    )
    assert result.actions[0].status == "skipped"
    assert result.actions[0].error_code == NO_RECIPIENT_CODE
    assert invoker.calls == []


def test_fixed_recipient_and_literal_content() -> None:
    definition = _email_fields()
    accepted = _accept(definition, {"message": "Need a quote"})
    action = email_send_action(
        key="notify_sales",
        mapping={"text": "message"},
        constants={
            "to": "sales@example.com",
            "subject": "We received your request",
        },
    )
    invoker = RecordingCapabilityInvoker()
    execute_post_submit_actions(
        accepted,
        FormPostSubmitPlan(actions=(action,)),
        context=_CTX,
        invoker=invoker,
        definition=definition,
    )
    assert invoker.calls[0]["payload"]["to"] == "sales@example.com"
    assert invoker.calls[0]["payload"]["subject"] == "We received your request"
    assert invoker.calls[0]["payload"]["text"] == "Need a quote"
    assert "email" not in accepted.submission.values


def test_double_brace_literal_is_not_interpolated() -> None:
    action = email_send_action(
        mapping={"to": "email"},
        constants={"subject": "Thanks, {{name}}", "text": "Hello {{name}}"},
    )
    built = build_email_send_payload(action, {"email": "ada@example.com", "name": "Ada"})
    assert built.payload is not None
    assert built.payload["subject"] == "Thanks, {{name}}"
    assert built.payload["text"] == "Hello {{name}}"


def test_missing_optional_html_omitted() -> None:
    action = email_send_action(
        mapping={"to": "email", "text": "message", "html": "note"},
        constants={"subject": "Hi"},
    )
    built = build_email_send_payload(
        action,
        {"email": "ada@example.com", "message": "Hello"},
    )
    assert built.payload is not None
    assert "html" not in built.payload


def test_explicit_null_recipient_skips() -> None:
    action = email_send_action()
    built = build_email_send_payload(
        action,
        {"email": None, "message": "Hello"},
    )
    assert built.skipped is True
    assert built.error_code == NO_RECIPIENT_CODE


def test_number_and_bool_and_file_mappings_rejected() -> None:
    definition = _email_fields(file=True)
    number = email_send_action(
        mapping={"to": "email", "subject": "budget"},
        constants={"text": "Hi"},
    )
    assert "unsupported_email_source_type" in validate_email_mapping(number, definition)
    boolean = email_send_action(
        mapping={"to": "opt_in"},
        constants={"subject": "Hi", "text": "Hi"},
    )
    assert "unsupported_email_source_type" in validate_email_mapping(
        boolean, definition
    )
    resume = email_send_action(
        mapping={"to": "email", "text": "resume"},
        constants={"subject": "Hi"},
    )
    assert "unsupported_email_file_mapping" in validate_email_mapping(
        resume, definition
    )
    runtime = build_email_send_payload(
        resume,
        {"email": "ada@example.com", "resume": FormFileRef(file_id=_FILE_1)},
    )
    assert runtime.skipped is False
    assert runtime.error_code == "unsupported_email_file_mapping"
    assert runtime.payload is None


def test_forbidden_email_constants_and_targets() -> None:
    definition = _email_fields()
    sender = FormPostSubmitAction(
        key="send_confirmation",
        action_type="email.send",
        mapping={"to": "email", "text": "message"},
        constants={"subject": "Hi", "from_address": "ops@example.com"},
    )
    assert "unexpected_email_constant" in validate_email_mapping(sender, definition)
    cc = email_send_action(
        mapping={"to": "email", "cc": "email", "text": "message"},
        constants={"subject": "Hi"},
    )
    assert "unknown_email_target" in validate_email_mapping(cc, definition)


def test_crm_failure_does_not_suppress_email() -> None:
    definition = contact_block_compatible_definition()
    accepted = _accept(
        definition,
        {"name": "Ada", "email": "ada@example.com", "message": "Hi"},
    )
    invoker = RecordingCapabilityInvoker(
        {
            "crm.contact.upsert": FormCapabilityInvokeResult(
                status="failed",
                error_code="binding_ambiguous",
            )
        }
    )
    result = execute_post_submit_actions(
        accepted,
        contact_compatible_plan(),
        context=_CTX,
        invoker=invoker,
        definition=definition,
    )
    by_key = {item.action_key: item for item in result.actions}
    assert by_key["sync_crm"].status == "failed"
    assert by_key["send_confirmation"].status == "succeeded"
    assert [call["capability"] for call in invoker.calls] == [
        "crm.contact.upsert",
        "email.send",
        "automation.workflow.trigger",
    ]


def test_email_failure_does_not_suppress_automation_or_rollback() -> None:
    definition = contact_block_compatible_definition()
    accepted = _accept(
        definition,
        {"name": "Ada", "email": "ada@example.com", "message": "Hi"},
    )
    store = InMemoryFormSubmissionStore()
    invoker = RecordingCapabilityInvoker(
        {
            "email.send": FormCapabilityInvokeResult(
                status="failed",
                error_code="email_unbound",
            )
        }
    )
    result = execute_post_submit_actions(
        accepted,
        contact_compatible_plan(),
        context=_CTX,
        invoker=invoker,
        definition=definition,
        store=store,
        persist_first=True,
    )
    by_key = {item.action_key: item for item in result.actions}
    assert by_key["sync_crm"].status == "succeeded"
    assert by_key["send_confirmation"].status == "failed"
    assert by_key["send_confirmation"].error_code == "email_unbound"
    assert by_key["notify_automation"].status == "succeeded"
    assert get_form_submission(
        store, FormPersistenceContext(project_id="prj_a"), _FSB_A
    ) is not None
    assert accepted.submission.values.get("email_status") is None


def test_persist_first_failure_does_not_send_email() -> None:
    definition = contact_block_compatible_definition()
    accepted = _accept(
        definition,
        {"name": "Ada", "email": "ada@example.com", "message": "Hi"},
    )
    invoker = RecordingCapabilityInvoker()
    result = execute_post_submit_actions(
        accepted,
        contact_compatible_plan(),
        context=_CTX,
        invoker=invoker,
        definition=definition,
        store=BoomStore(),
        persist_first=True,
    )
    assert result.plan_error == "persistence_failed"
    assert invoker.calls == []


def test_two_submissions_two_emails_same_recipient() -> None:
    definition = _email_fields()
    plan = FormPostSubmitPlan(actions=(email_send_action(),))
    invoker = RecordingCapabilityInvoker()
    for submission_id in (_FSB_A, _FSB_B):
        accepted = _accept(
            definition,
            {"email": "jane@example.com", "message": "Hi"},
            submission_id=submission_id,
        )
        execute_post_submit_actions(
            accepted, plan, context=_CTX, invoker=invoker, definition=definition
        )
    keys = [call["idempotency_key"] for call in invoker.calls]
    assert keys == [
        action_idempotency_key(_FSB_A, "send_confirmation"),
        action_idempotency_key(_FSB_B, "send_confirmation"),
    ]


def test_retry_identity_is_submission_and_action_key() -> None:
    assert action_idempotency_key(_FSB_A, "send_confirmation") == (
        f"{_FSB_A}:send_confirmation"
    )


def test_provider_specific_email_does_not_fallback() -> None:
    definition = _email_fields()
    accepted = _accept(definition, {"email": "ada@example.com", "message": "Hi"})
    plan = FormPostSubmitPlan(
        actions=(
            FormPostSubmitAction(
                key="resend_direct",
                action_type="resend.send_email",
                mapping={"to": "email"},
                constants={"subject": "Hi", "text": "Hi"},
                provider_specific=True,
            ),
        )
    )
    assert validate_post_submit_plan(plan, definition) == ()
    invoker = RecordingCapabilityInvoker(
        {
            "resend.send_email": FormCapabilityInvokeResult(
                status="failed",
                error_code="provider_unavailable",
            )
        }
    )
    result = execute_post_submit_actions(
        accepted, plan, context=_CTX, invoker=invoker, definition=definition
    )
    assert result.actions[0].error_code == "provider_unavailable"
    assert [call["capability"] for call in invoker.calls] == ["resend.send_email"]


def test_contact_compatible_plan_is_generic_email_send() -> None:
    plan = contact_compatible_plan()
    email = plan.actions[1]
    assert email.action_type == "email.send"
    assert email.mapping == {"to": "email", "text": "message"}
    assert email.constants == {"subject": "Contact received"}
    definition = contact_block_compatible_definition()
    assert validate_post_submit_plan(plan, definition) == ()


def test_legacy_contact_formatter_is_not_generic_renderer() -> None:
    payload = contact_legacy_notification_payload(
        {
            "name": "Ada",
            "email": "ada@example.com",
            "phone": "555",
            "message": "Hello",
        },
        notify_to="sales@example.com, ops@example.com",
    )
    assert payload["to"] == ["sales@example.com", "ops@example.com"]
    assert payload["subject"] == "New contact form submission from Ada"
    assert "Name: Ada" in payload["text"]
    assert payload["reply_to"] == "ada@example.com"
    generic = build_email_send_payload(
        email_send_action(),
        {"email": "ada@example.com", "name": "Ada", "message": "Hello"},
    )
    assert generic.payload is not None
    assert generic.payload["subject"] == "Contact received"
    assert generic.payload["text"] == "Hello"
    assert "Name: Ada" not in generic.payload["text"]
