"""Tiny authenticated SMTP mailer endpoint (Flask + Passenger) for cPanel.

VPS mengirim POST JSON `{"to", "subject", "body"}` dengan header `X-Auth-Token`.
Endpoint ini mengirim lewat **SMTP lokal** (127.0.0.1) sehingga mengikuti jalur
pengiriman yang sama dengan webmail cPanel (Exim -> MailChannels), bukan
submission eksternal yang bisa terfilter/nyangkut.
"""

from __future__ import annotations

import hmac
import os
import smtplib
import ssl
from email.message import EmailMessage
from email.utils import formataddr

from dotenv import load_dotenv
from flask import Flask, jsonify, request

load_dotenv()  # memuat .env bila ada; no-op kalau tidak ada

app = Flask(__name__)
app.config["MAX_CONTENT_LENGTH"] = int(os.getenv("MAILER_MAX_BYTES", str(256 * 1024)))


def _split(raw: str | None) -> list[str]:
    if not raw:
        return []
    return [item.strip() for item in raw.replace(";", ",").split(",") if item.strip()]


def _token_ok() -> bool:
    expected = os.getenv("MAILER_TOKEN", "")
    provided = request.headers.get("X-Auth-Token", "")
    return bool(expected) and hmac.compare_digest(expected, provided)


def _recipients(raw: object) -> list[str]:
    if isinstance(raw, str):
        return _split(raw)
    if isinstance(raw, list):
        return [str(item).strip() for item in raw if str(item).strip()]
    return []


def _send(to: list[str], subject: str, body: str, reply_to: str) -> None:
    sender = os.getenv("MAILER_FROM", "").strip()
    from_name = os.getenv("MAILER_FROM_NAME", "").strip()
    host = os.getenv("MAILER_SMTP_HOST", "127.0.0.1")
    port = int(os.getenv("MAILER_SMTP_PORT", "25"))
    security = os.getenv("MAILER_SMTP_SECURITY", "none").strip().lower()
    user = os.getenv("MAILER_SMTP_USER", "")
    password = os.getenv("MAILER_SMTP_PASSWORD", "")
    timeout = float(os.getenv("MAILER_TIMEOUT", "15"))

    msg = EmailMessage()
    msg["From"] = formataddr((from_name, sender)) if from_name else sender
    msg["To"] = ", ".join(to)
    if reply_to:
        msg["Reply-To"] = reply_to
    msg["Subject"] = subject
    msg.set_content(body)

    context = ssl.create_default_context()
    if security == "ssl":
        server: smtplib.SMTP = smtplib.SMTP_SSL(host, port, timeout=timeout, context=context)
    else:
        server = smtplib.SMTP(host, port, timeout=timeout)

    with server:
        server.ehlo()
        if security == "starttls":
            server.starttls(context=context)
            server.ehlo()
        if user or password:
            server.login(user, password)
        server.send_message(msg)


@app.get("/health")
def health():
    return jsonify({"ok": True})


@app.post("/send")
def send():
    if not _token_ok():
        return jsonify({"ok": False, "error": "unauthorized"}), 401

    if not os.getenv("MAILER_FROM", "").strip():
        return jsonify({"ok": False, "error": "server_misconfigured"}), 500

    data = request.get_json(silent=True) or {}
    to = _recipients(data.get("to"))
    subject = str(data.get("subject") or "").strip()
    body = str(data.get("body") or "")
    reply_to = str(data.get("reply_to") or "").strip()

    if not to:
        return jsonify({"ok": False, "error": "to_required"}), 400
    if not subject:
        return jsonify({"ok": False, "error": "subject_required"}), 400

    try:
        _send(to, subject, body, reply_to)
    except (smtplib.SMTPException, OSError, ValueError) as exc:
        app.logger.exception("gagal mengirim email")
        return jsonify({"ok": False, "error": "send_failed", "detail": str(exc)[:300]}), 502

    return jsonify({"ok": True, "recipients": to})


if __name__ == "__main__":
    app.run(host=os.getenv("MAILER_DEV_HOST", "127.0.0.1"), port=int(os.getenv("MAILER_DEV_PORT", "5000")))
