import smtplib
import os
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from .app.helpers.validator import email_validator
from .app.exceptions.email_expection import (
    InvalidEmailSubject,
    InvalidEmailReceiverAddress,
    InvalidEmailBody
)


class RapidEmailNotificationSMTP:

    def __init__(self, smtp_sender_email, smtp_password):
        self.smtp_sender_email = smtp_sender_email
        self.smtp_password = smtp_password

    def add_cc(self, cc):
        if type(cc) != list:
            raise InvalidEmailReceiverAddress('Invalid cc"s receiver address.')

        cc = [i for i in cc if email_validator(i)]
        return ', '.join(cc)

    def add_attachement(self, attach):
        if type(attach) != str:
            print(f'Invalid attach file. {attach}')
            return False

        if not os.path.exists(attach):
            print(f'Invalid attach file. {attach}')
            return False

        # Open the file as binary mode
        with open(attach, 'rb') as file:
            attach_file = file.read()

        mime_base_payload = MIMEBase('application', 'octate-stream')
        mime_base_payload.set_payload(attach_file)

        # encode the attachment
        encoders.encode_base64(mime_base_payload)

        file_name = attach.split('/')[-1]

        # add payload header with filename
        mime_base_payload.add_header('Content-Disposition', "attachment; filename= %s" % file_name)

        return mime_base_payload

    def send_email(self, to, subject, content, cc=None, attach=None):

        """
            This function takes some parameters as input and returns True or None.

            Parameters:
            to (list): Receiver's address Ex:- ['abc@gmail.com', 'xyz@gmail.com'] (mandatory)
            subject (str): Email Subject Ex: "Test Subject" (mandatory)
            content (Str): Email Body Ex: Hello Dear, This is the fake email body. (mandatory)
            cc (list): Receiver's address Ex: ['mno@gmail.com', 'tuv@gmail.com'] (optional)
            attach (str): path/file_name  (optional)

            Returns:
            str: 'True' if function run successfully.
        """

        try:

            mime_multipart_obj = MIMEMultipart('alternative')
            mime_multipart_obj['From'] = self.smtp_sender_email
            if type(subject) != str:
                raise InvalidEmailSubject('Invalid subject.')
            mime_multipart_obj['Subject'] = subject

            if type(to) != list:
                raise InvalidEmailReceiverAddress('Invalid to" receiver address.')

            to = [i for i in to if email_validator(i)]
            mime_multipart_obj['To'] = ', '.join(to)
            receiver_email_id = to

            if cc:
                mime_multipart_obj['Cc'] = self.add_cc(cc)
                receiver_email_id += cc

            if type(content) != str:
                raise InvalidEmailBody('Invalid email body.')

            mime_multipart_obj.attach(MIMEText(content, 'plain'))

            if attach:
                print.info(f"{os.getcwd()} current path")
                print.info(f"{os.listdir()} list of directory.")
                response_attach_file = self.add_attachement(attach)
                if response_attach_file:
                    mime_multipart_obj.attach(response_attach_file)

            # Connect to the SMTP server
            session = smtplib.SMTP('smtp.gmail.com', 587)

            # enable security
            session.starttls()

            # login with mail_id and password
            session.login(self.smtp_sender_email, self.smtp_password)

            mime_multipart_text = mime_multipart_obj.as_string()

            session.sendmail(self.smtp_sender_email, receiver_email_id, mime_multipart_text)

            session.quit()

            print(f"Email send successfully.")

        except Exception as e:
            raise e

        return True

