from email.mime.base import MIMEBase
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email_manager.providers.base import BaseEmailProvider
from email import encoders


class SMTPProvider(BaseEmailProvider):
    def __init__(self, smtp_params: dict, config):
        self.host = smtp_params.get("host")
        self.port = smtp_params.get("port")
        self.from_email = smtp_params.get("from_email")
        self.password = smtp_params.get("password")
        self.use_tls = smtp_params.get("use_tls")
        self.timeout = config.timeout

    def send_email(self, to: str, subject: str, body: str, **kwargs) -> bool:
        try:
            message = self._create_message(to, subject, body)
            with self._connect_smtp() as smtp:
                smtp.send_message(message)
            return True
        except Exception as e:
            self._handle_error(e)
            return False

    def send_bulk_email(self, recipients: list, subject: str, body: str) -> dict:
        results = {}
        for recipient in recipients:
            results[recipient] = self.send_email(recipient, subject, body)
        return results

    def _create_message(self, to: str, subject: str, body: str, bcc: str, attachments: list) -> MIMEMultipart:
        msg = MIMEMultipart()
        msg["From"] = self.from_email
        msg["To"] = to
        msg["Subject"] = subject
        msg.attach(MIMEText(body, "html"))
        to_addrs += bcc
        if attachments:
            for attachment in attachments:
                part = MIMEBase('application', 'octet-stream')
                with open(attachment, 'rb') as f:
                    part.set_payload(f.read())
                encoders.encode_base64(part)
                part.add_header('Content-Disposition', 'attachment',
                                filename=attachment.split('/')[-1])
                msg.attach(part)
        return msg

    def _connect_smtp(self) -> smtplib.SMTP:
        try:
            smtp = smtplib.SMTP(self.host, self.port, timeout=self.timeout)
            if self.use_tls:
                smtp.starttls()
            smtp.login(self.from_email, self.password)
            return smtp
        except Exception as error:
            print(error)
            
            
    def _handle_error(self, error: Exception):
        print(f"[SMTP Error] {error}")

    def get_provider_name(self) -> str:
        return "SMTPProvider"