import smtplib
import logging
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import io
from django.template.loader import get_template
from django.conf import settings
import re

logger = logging.getLogger(__name__)

class Emailer:
    """
    This class is used to send emails
    """
    def __init__(self):
        self.sender = settings.EMAIL_HOST_USER
        self.password = settings.EMAIL_HOST_PASSWORD
        self.host = settings.EMAIL_HOST
        self.port = settings.EMAIL_PORT
        print(settings.EMAIL_HOST, settings.EMAIL_PORT, settings.EMAIL_HOST_USER, settings.EMAIL_HOST_PASSWORD)

    def send(self, template_name: str, recipient: str, subject: str,
             context_dict=None) -> None:
        """
        Sends the email to all recipients
        param template_name: The name of the template
        param recipient : The email address of the recipient
        param context_dict: The context to render the template with
        param kwargs: Additional arguments
            - subject (str): The subject of the email. Replace the template subject if provided.
        """

        if settings.DEBUG:
            logger.info('Sending email')

        # Checking context
        if context_dict is None:
            context_dict = {}

        # Checking recipient
        if not re.match(r"[^@]+@[^@]+\.[^@]+", recipient):
            logger.error('Invalid receiver email')
            return

        # Getting the template
        try:
            template_html = get_template(f'emails/{template_name}.html')
            template_text = get_template(f'emails/{template_name}.txt')
        except Exception as e:
            logger.error(f'Template "{template_name}" does not exist: {e}')
            return

        with smtplib.SMTP(self.host, self.port) as server:
            server.ehlo()
            server.starttls()
            server.ehlo()
            server.login(self.sender, self.password)

            # Creating the messages
            message = MIMEMultipart("alternative")
            message["Subject"] = subject
            message["From"] = settings.EMAIL_HOST_USER
            message["To"] = recipient

            # Add HTML/plain-text parts to MIMEMultipart message
            # The email client will try to render the last part first
            message.attach(MIMEText(template_text.render(context_dict), "plain"))
            message.attach(MIMEText(template_html.render(context_dict), "html"))

            server.sendmail(
                self.sender, recipient, message.as_string()
            )

