import asyncio
import smtplib
import ssl
from email.message import EmailMessage
from pathlib import Path

from .config import get_settings

settings = get_settings()


class NotificationUnavailable(RuntimeError):
    pass


def _send_sync(message: EmailMessage) -> None:
    if not settings.notifications_enabled:
        raise NotificationUnavailable("Les notifications sont désactivées dans la configuration.")
    if not settings.smtp_host:
        raise NotificationUnavailable("SMTP_HOST n'est pas renseigné.")

    if settings.smtp_use_ssl:
        context = ssl.create_default_context()
        with smtplib.SMTP_SSL(settings.smtp_host, settings.smtp_port, context=context, timeout=20) as client:
            if settings.smtp_user:
                client.login(settings.smtp_user, settings.smtp_password or "")
            client.send_message(message)
        return

    with smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=20) as client:
        client.ehlo()
        if settings.smtp_use_tls:
            client.starttls(context=ssl.create_default_context())
            client.ehlo()
        if settings.smtp_user:
            client.login(settings.smtp_user, settings.smtp_password or "")
        client.send_message(message)


async def send_email(
    recipients: list[str],
    subject: str,
    text_body: str,
    html_body: str | None = None,
    attachment_bytes: bytes | None = None,
    attachment_name: str | None = None,
) -> None:
    valid_recipients = [address.strip() for address in recipients if address and address.strip()]
    if not valid_recipients:
        raise NotificationUnavailable("Aucun destinataire n'est configuré.")

    message = EmailMessage()
    message["From"] = settings.smtp_from
    message["To"] = ", ".join(valid_recipients)
    message["Subject"] = subject
    message.set_content(text_body)
    if html_body:
        message.add_alternative(html_body, subtype="html")
    if attachment_bytes and attachment_name:
        message.add_attachment(
            attachment_bytes,
            maintype="application",
            subtype="pdf",
            filename=Path(attachment_name).name,
        )

    await asyncio.to_thread(_send_sync, message)
