from redmail import EmailSender
from typing import List, Optional, Dict
from pydantic import BaseModel
from config import Configs
from contextlib import contextmanager


class EmailSendModel(BaseModel):
    subject: str
    html: str = ""
    receivers: List[str]
    text: Optional[str] = ""
    cc: Optional[List[str]] = None
    bcc: Optional[List[str]] = None
    headers: Optional[Dict] = None
    attachments: Optional[Dict] = None


class EmailSession:

    def __init__(self, email_sender):
        self.email_sender = email_sender

    def send(self, params: EmailSendModel) -> bool:
        """Send email using this session."""
        if not Configs.is_send:
            print("Email sending is disabled", params)
            return False

        receivers = [Configs.USERNAME]
        self.email_sender.send(
            subject=params.subject,
            receivers=receivers,
            text=params.text + f" : Gonderilen [{str(receivers)}]",
            html=params.html,
            cc=params.cc,
            bcc=params.bcc,
            headers=params.headers or {},
            attachments=params.attachments or {},
        )
        return True


class EmailService:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(EmailService, cls).__new__(cls)
        return cls._instance

    @classmethod
    @contextmanager
    def new_session(cls):
        """Create and yield a new email session with active connection."""
        email_sender = EmailSender(**Configs.as_dict())
        session = EmailSession(email_sender)
        try:
            email_sender.connect()
            yield session
        except Exception as e:
            print(f"Error with email connection: {e}")
            raise
        finally:
            email_sender.close()

    @classmethod
    def send_email(cls, session: EmailSession, params: EmailSendModel) -> bool:
        """Send email using the provided session."""
        return session.send(params)
