from __future__ import annotations

import smtplib
from dataclasses import dataclass
from email.message import EmailMessage

from app.core.config import settings


@dataclass
class SentEmail:
    to: str
    subject: str
    body: str
    template: str


class MemoryMailer:
    def __init__(self) -> None:
        self.sent: list[SentEmail] = []

    def send(self, to: str, subject: str, body: str, template: str) -> None:
        self.sent.append(SentEmail(to=to, subject=subject, body=body, template=template))

    def clear(self) -> None:
        self.sent.clear()

    def latest_token(self, recipient: str, template: str) -> str | None:
        for message in reversed(self.sent):
            if message.to == recipient and message.template == template:
                for line in message.body.splitlines():
                    if line.startswith("TOKEN:"):
                        return line.split(":", 1)[1].strip()
        return None


class SmtpMailer:
    def send(self, to: str, subject: str, body: str, template: str) -> None:
        _ = template
        message = EmailMessage()
        message["From"] = settings.smtp_from
        message["To"] = to
        message["Subject"] = subject
        message.set_content(body)
        with smtplib.SMTP(settings.smtp_host, settings.smtp_port, timeout=10) as smtp:
            if settings.smtp_user:
                smtp.login(settings.smtp_user, settings.smtp_password)
            smtp.send_message(message)


memory_mailer = MemoryMailer()


def get_mailer():
    if settings.email_delivery_mode == "memory":
        return memory_mailer
    return SmtpMailer()


def send_template_email(to: str, template: str, subject: str, body: str) -> None:
    get_mailer().send(to=to, subject=subject, body=body, template=template)
