"""Postmark transactional email delivery via httpx.

Non-fatal: every public function returns ``True`` on success and
``False`` on failure.  Email must never block a billing webhook.
"""

from __future__ import annotations

import asyncio
import logging
from typing import Any

import httpx

_log = logging.getLogger(__name__)

_POSTMARK_URL = "https://api.postmarkapp.com/email/withTemplate"
_FROM_ADDRESS = "notifications@complyform.dev"
_RETRY_DELAY_SECONDS = 5


async def _get_postmark_token() -> str:
    """Retrieve Postmark server token from Secret Manager."""
    from google.cloud import secretmanager

    client = secretmanager.SecretManagerServiceClient()
    name = "projects/complyform-prod/secrets/postmark-server-token/versions/latest"
    response = client.access_secret_version(request={"name": name})
    return response.payload.data.decode("utf-8")


async def send_template_email(
    to: str,
    template_alias: str,
    template_model: dict[str, Any],
) -> bool:
    """Send transactional email via Postmark.

    Returns ``True`` on success, ``False`` on failure.  Never raises —
    email is non-fatal.

    Error handling:
    - HTTP 5xx: retry once after 5-second delay
    - Persistent failure: return ``False`` (caller sets
      ``email_delivery_failed`` in Firestore)
    - Never blocks the billing webhook
    """
    try:
        token = await _get_postmark_token()
    except Exception:
        _log.exception("Failed to retrieve Postmark token from Secret Manager")
        return False

    headers = {
        "Accept": "application/json",
        "Content-Type": "application/json",
        "X-Postmark-Server-Token": token,
    }
    payload = {
        "From": _FROM_ADDRESS,
        "To": to,
        "TemplateAlias": template_alias,
        "TemplateModel": template_model,
    }

    for attempt in range(2):
        try:
            async with httpx.AsyncClient(timeout=15.0) as client:
                resp = await client.post(_POSTMARK_URL, json=payload, headers=headers)

            if resp.status_code == 200:
                return True

            if resp.status_code >= 500 and attempt == 0:
                _log.warning(
                    "Postmark 5xx (%s) for %s, retrying in %ss",
                    resp.status_code,
                    template_alias,
                    _RETRY_DELAY_SECONDS,
                )
                await asyncio.sleep(_RETRY_DELAY_SECONDS)
                continue

            _log.error(
                "Postmark error %s for %s: %s",
                resp.status_code,
                template_alias,
                resp.text,
            )
            return False

        except Exception:
            if attempt == 0:
                _log.exception(
                    "Postmark request failed for %s, retrying", template_alias
                )
                await asyncio.sleep(_RETRY_DELAY_SECONDS)
                continue
            _log.exception("Postmark request failed for %s after retry", template_alias)
            return False

    return False
