"""SMTP email sending -- password resets and battery-threshold alerts.

Config lives in the server_settings singleton row (admin-configured via
/admin, see routers/pages.py), not env vars -- it's operator
infrastructure a household admin sets up once through the UI, same
spirit as the rest of this project's "no separate config file" stance
post-redesign. Uses stdlib smtplib; no new dependency.

send_email() never raises -- a broken mail server shouldn't 500 a
password-reset request or a battery report; callers get a bool and log
a warning on failure."""

from __future__ import annotations

import email.utils
import logging
import smtplib
import ssl
from email.mime.text import MIMEText

from .models import ServerSettings

logger = logging.getLogger(__name__)

SMTP_TIMEOUT_S = 10


def send_email(settings: ServerSettings, to_address: str, subject: str, body: str) -> bool:
    if not settings.smtp_host or not to_address:
        return False

    msg = MIMEText(body)
    msg["Subject"] = subject
    msg["From"] = settings.smtp_from_address or settings.smtp_username or "noreply@localhost"
    msg["To"] = to_address
    # email.mime doesn't set either of these on its own -- and a missing
    # Message-ID in particular is enough for a strict content filter
    # (e.g. Amavis's header-sanity check) to quarantine an otherwise
    # cleanly SPF/DKIM/DMARC-passing message outright. Domain in the
    # generated id matches the From address so it's traceable back here.
    msg["Date"] = email.utils.formatdate(localtime=True)
    msg["Message-ID"] = email.utils.make_msgid(domain=msg["From"].rsplit("@", 1)[-1])

    try:
        # "ssl" (implicit TLS, port 465 typically) needs a TLS socket from
        # the very first byte -- SMTP_SSL, not SMTP+starttls(). Connecting
        # a plaintext SMTP() to a TLS-only port fails outright (garbled
        # banner/timeout), it doesn't degrade gracefully, so this has to
        # be a real branch rather than "starttls() or not".
        if settings.smtp_encryption == "ssl":
            with smtplib.SMTP_SSL(
                settings.smtp_host, settings.smtp_port,
                timeout=SMTP_TIMEOUT_S, context=ssl.create_default_context(),
            ) as smtp:
                if settings.smtp_username:
                    smtp.login(settings.smtp_username, settings.smtp_password)
                smtp.send_message(msg)
        else:
            with smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=SMTP_TIMEOUT_S) as smtp:
                if settings.smtp_encryption == "starttls":
                    smtp.starttls(context=ssl.create_default_context())
                if settings.smtp_username:
                    smtp.login(settings.smtp_username, settings.smtp_password)
                smtp.send_message(msg)
        return True
    except (OSError, smtplib.SMTPException, ssl.SSLError) as e:
        logger.warning("Failed to send email to %s: %s", to_address, e)
        return False
