"""Send an email via the Gmail API using the same domain-wide delegation that
powers capture and draft creation.

The DWD grant on this deployment includes the `gmail.compose` scope (verified
2026-06-15: token mint + a live messages.send both succeed), and `gmail.compose`
authorizes `users.messages.send`. So CRM-originated mail (the daily digest) can
send through the existing service account — no SMTP account, no app password, no
admin change. Sends impersonating `sender_email`, which must be a Workspace user
in the delegated domain. Mirrors the REST pattern in compose.py; stdlib only.
"""
import base64
import email.message
import json
import os
import urllib.error
import urllib.parse
import urllib.request

from . import config as _cfg
from . import credentials as _creds


def gmail_available():
    """True when DWD send is usable: integration enabled, DWD auth, key present."""
    cfg = _cfg.CONFIG
    if not cfg.enabled or cfg.primary_auth != "dwd":
        return False
    return bool(cfg.dwd_key_path) and os.path.exists(cfg.dwd_key_path)


def _build_raw(from_addr, to_addrs, subject, body):
    msg = email.message.EmailMessage()
    msg["From"] = from_addr
    msg["To"] = ", ".join(to_addrs)
    msg["Subject"] = subject or "(no subject)"
    msg.set_content(body or "")
    return base64.urlsafe_b64encode(msg.as_bytes()).decode("ascii")


def send_via_gmail(sender_email, to_addrs, subject, body, conn=None):
    """Send one message as `sender_email` to `to_addrs` via the Gmail API (DWD).
    Returns {'sent_to', 'from', 'message_id'}; raises on failure."""
    if isinstance(to_addrs, str):
        to_addrs = [to_addrs]
    to_addrs = [a for a in (str(x).strip() for x in to_addrs) if a]
    if not to_addrs:
        raise ValueError("no recipients")
    if not sender_email:
        raise ValueError("no sender_email (DWD impersonation needs a domain user)")

    # conn is only consulted by the OAuth provider path; the DWD provider (the one
    # used here) reads the service-account key from disk and ignores it.
    provider = _creds.build_provider(lambda: conn)
    token = provider.access_token_for(sender_email, _creds.GMAIL_COMPOSE_SCOPE).token
    raw = _build_raw(sender_email, to_addrs, subject, body)
    url = ("https://gmail.googleapis.com/gmail/v1/users/"
           f"{urllib.parse.quote(sender_email)}/messages/send")
    req = urllib.request.Request(
        url, data=json.dumps({"raw": raw}).encode("utf-8"), method="POST",
        headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"})
    try:
        with urllib.request.urlopen(req, timeout=20) as resp:
            result = json.loads(resp.read())
    except urllib.error.HTTPError as e:
        detail = e.read().decode("utf-8", "replace")[:300]
        raise RuntimeError(f"Gmail API send failed for {sender_email} (HTTP {e.code}): {detail}")
    except OSError as e:  # URLError/timeout/DNS (URLError subclasses OSError)
        raise RuntimeError(f"Gmail API unreachable: {e}")
    return {"sent_to": to_addrs, "from": sender_email, "message_id": result.get("id")}
