"""
Email SMTP sender (worker) – invio notifiche via aiosmtplib.

Copia del sender backend: i due container sono separati.
"""

from datetime import datetime
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import aiosmtplib

DEFAULT_TIMEOUT = 15.0


class EmailSMTPError(Exception):
    def __init__(self, message: str, smtp_code: int | None = None):
        super().__init__(message)
        self.smtp_code = smtp_code


async def send_email_notification(
    smtp_host: str,
    smtp_port: int,
    smtp_user: str,
    smtp_password: str,
    from_email: str,
    to_email: str,
    subject: str,
    body_text: str,
    body_html: str | None = None,
    from_name: str = "PEChub Notifiche",
    use_tls: bool = True,
    use_starttls: bool = False,
    timeout: float = DEFAULT_TIMEOUT,
) -> None:
    """
    Invia un'email di notifica via SMTP.

    Raises:
        EmailSMTPError: in caso di errori di autenticazione, connessione o invio
    """
    msg = MIMEMultipart("alternative")
    msg["Subject"] = subject
    msg["From"] = f"{from_name} <{from_email}>" if from_name else from_email
    msg["To"] = to_email
    msg["Date"] = datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S +0000")
    msg["X-Mailer"] = "PEChub/1.0"

    msg.attach(MIMEText(body_text, "plain", "utf-8"))
    if body_html:
        msg.attach(MIMEText(body_html, "html", "utf-8"))

    try:
        await aiosmtplib.send(
            msg,
            hostname=smtp_host,
            port=smtp_port,
            username=smtp_user,
            password=smtp_password,
            use_tls=use_tls,
            start_tls=use_starttls,
            timeout=timeout,
        )
    except aiosmtplib.SMTPAuthenticationError as exc:
        raise EmailSMTPError(
            f"Autenticazione SMTP fallita: {exc}", smtp_code=535
        ) from exc
    except aiosmtplib.SMTPConnectError as exc:
        raise EmailSMTPError(
            f"Connessione SMTP fallita a {smtp_host}:{smtp_port}: {exc}"
        ) from exc
    except aiosmtplib.SMTPException as exc:
        raise EmailSMTPError(f"Errore SMTP: {exc}") from exc
    except Exception as exc:
        raise EmailSMTPError(f"Errore invio email: {exc}") from exc
