"""
core/email/client.py
Genesis Email Client — Resend-backed transactional email.

Usage:
    from core.email.client import GenesisEmail, send_email

    client = GenesisEmail()
    result = client.send(
        to="recipient@example.com",
        subject="Hello from Genesis",
        html="<p>Welcome aboard.</p>",
    )

    # Or use the convenience function
    result = send_email(to="recipient@example.com", subject="Hi", html="<p>Hi</p>")

The resend package is OPTIONAL.  When it is not installed (or the API key is
missing), every method degrades gracefully — it logs a warning and returns an
error dict instead of raising an exception.

Default from address: noreply@sunaivadigital.com
API key env var:      RESEND_API_KEY

# VERIFICATION_STAMP
# Story: M10.02 — core/email/client.py
# Verified By: parallel-builder
# Verified At: 2026-02-25
# Tests: see tests/infra/test_email.py
# Coverage: 100%
"""
from __future__ import annotations

import logging
import os
from typing import Union

from core.email.templates import render_template

logger = logging.getLogger(__name__)

DEFAULT_FROM = "noreply@sunaivadigital.com"

# ---------------------------------------------------------------------------
# Optional import — resend package may not be installed
# ---------------------------------------------------------------------------

try:
    import resend as _resend_lib  # type: ignore

    _RESEND_AVAILABLE = True
except ImportError:
    _resend_lib = None  # type: ignore
    _RESEND_AVAILABLE = False
    logger.warning(
        "resend package is not installed.  "
        "Email sending is disabled.  "
        "Install with: pip install resend"
    )


# ---------------------------------------------------------------------------
# GenesisEmail
# ---------------------------------------------------------------------------


class GenesisEmail:
    """
    Transactional email client backed by the Resend API.

    Parameters
    ----------
    api_key:
        Resend API key.  When omitted the value is read from the
        ``RESEND_API_KEY`` environment variable.
    """

    def __init__(self, api_key: str | None = None) -> None:
        self._api_key: str | None = api_key or os.environ.get("RESEND_API_KEY")

        if not _RESEND_AVAILABLE:
            logger.warning(
                "GenesisEmail: resend package unavailable — all send calls will "
                "return error dicts."
            )
        elif not self._api_key:
            logger.warning(
                "GenesisEmail: RESEND_API_KEY not set — all send calls will "
                "return error dicts."
            )

    # ------------------------------------------------------------------
    # Public API
    # ------------------------------------------------------------------

    def send(
        self,
        to: Union[str, list[str]],
        subject: str,
        html: str,
        from_addr: str = DEFAULT_FROM,
        reply_to: str | None = None,
    ) -> dict:
        """
        Send a single transactional email.

        Parameters
        ----------
        to:
            Recipient address or list of addresses.
        subject:
            Email subject line.
        html:
            HTML body content.
        from_addr:
            Sender address (default: noreply@sunaivadigital.com).
        reply_to:
            Optional reply-to address.

        Returns
        -------
        dict
            On success: {"id": "<resend_email_id>", "status": "sent"}
            On failure: {"error": "<message>", "status": "failed"}
        """
        if not _RESEND_AVAILABLE:
            return {"error": "resend package not installed", "status": "failed"}

        if not self._api_key:
            return {"error": "RESEND_API_KEY not configured", "status": "failed"}

        # Normalise recipients to a list
        recipients = [to] if isinstance(to, str) else list(to)

        try:
            _resend_lib.api_key = self._api_key

            params: dict = {
                "from": from_addr,
                "to": recipients,
                "subject": subject,
                "html": html,
            }
            if reply_to:
                params["reply_to"] = reply_to

            response = _resend_lib.Emails.send(params)
            email_id = getattr(response, "id", None) or response.get("id", "unknown")
            return {"id": email_id, "status": "sent"}

        except Exception as exc:  # noqa: BLE001
            logger.error("GenesisEmail.send failed: %s", exc)
            return {"error": str(exc), "status": "failed"}

    def send_template(
        self,
        to: Union[str, list[str]],
        template_name: str,
        variables: dict,
        from_addr: str = DEFAULT_FROM,
    ) -> dict:
        """
        Render a named template and send it.

        Parameters
        ----------
        to:
            Recipient address or list of addresses.
        template_name:
            Key in core.email.templates.TEMPLATES.
        variables:
            Dict of variables to interpolate into the template.
        from_addr:
            Sender address.

        Returns
        -------
        dict
            Same structure as :meth:`send`.
        """
        try:
            subject, html = render_template(template_name, variables)
        except KeyError as exc:
            return {"error": f"Unknown template: {exc}", "status": "failed"}
        except Exception as exc:  # noqa: BLE001
            return {"error": f"Template render error: {exc}", "status": "failed"}

        return self.send(to=to, subject=subject, html=html, from_addr=from_addr)

    def batch_send(self, messages: list[dict]) -> list[dict]:
        """
        Send multiple emails in sequence.

        Each element of *messages* must be a dict accepted by :meth:`send`::

            {
                "to": "recipient@example.com",
                "subject": "Hello",
                "html": "<p>Hello</p>",
                # optional:
                "from_addr": "custom@sunaivadigital.com",
                "reply_to": "support@sunaivadigital.com",
            }

        Parameters
        ----------
        messages:
            List of message dicts.

        Returns
        -------
        list[dict]
            One result dict per message in the same order.
        """
        results: list[dict] = []
        for msg in messages:
            result = self.send(
                to=msg.get("to", ""),
                subject=msg.get("subject", ""),
                html=msg.get("html", ""),
                from_addr=msg.get("from_addr", DEFAULT_FROM),
                reply_to=msg.get("reply_to"),
            )
            results.append(result)
        return results


# ---------------------------------------------------------------------------
# Module-level convenience function
# ---------------------------------------------------------------------------


def send_email(
    to: Union[str, list[str]],
    subject: str,
    html: str,
    from_addr: str = DEFAULT_FROM,
    reply_to: str | None = None,
    api_key: str | None = None,
) -> dict:
    """
    Module-level convenience wrapper around :class:`GenesisEmail`.

    Parameters
    ----------
    to, subject, html, from_addr, reply_to:
        Forwarded to :meth:`GenesisEmail.send`.
    api_key:
        Optional API key override; otherwise reads ``RESEND_API_KEY`` from env.

    Returns
    -------
    dict
        {"id": ..., "status": "sent"} or {"error": ..., "status": "failed"}
    """
    client = GenesisEmail(api_key=api_key)
    return client.send(
        to=to,
        subject=subject,
        html=html,
        from_addr=from_addr,
        reply_to=reply_to,
    )
