import base64
from email.message import EmailMessage
from .service import get_service
from googleapiclient.errors import HttpError
from typing import List

def send_gmail(email_to: str, email_from: str, email_subject: str= " ",
               email_content: str= " "):
    """
    To email someone with your connected Google account.
    Connected account means the one whose credentials.json you are using.

    Args:
    email_to: Gmail of the receiver of the email. It is a must required field.
    email_from: Gmail of the sender of the email; It will always be the one you used to create the credentials.json file.
    email_subject: Subject of the Email to be sent.
    email_content: content of the email to be sent.

    Returns:
        Details of the message sent.

    Raises:
        Exception: For errors to send the email.

    Example:
        ```python
        def test_send_email():
            try:
                send_main = send_gmail(
                    email_to='',
                    email_from='',
                    email_subject='Testing Agent',
                    email_content='Testing Email Content!'
                )
                assert send_main is not None
                return f'Test case passed: {send_main}'
            except Exception as e:
                return f'Error creating emails: {e}'

        ```
    """
    try:
        service= get_service('gmail')
        message = EmailMessage()   
        message.set_content(email_content) 
        message["To"] = email_to
        message["From"] = email_from
        message["Subject"] = email_subject

        encoded_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
        create_message = {"raw": encoded_message}
        send_message = (
            service.users()
            .messages()
            .send(userId="me", body=create_message)
            .execute()
        )
        return send_message
    except HttpError as error:
        raise Exception(f"An error occurred: {error}")

def get_emails(num_emails: int)-> List:
    """Get the given number of latest unread emails from the gmail.
    we will only get Subject, and Sender email because we will be passing this to the LLM.
    For the privacy of a sender try not getting the sender email too.

    -> It will only get your primary emails.

    The limit of specific number of emails is being set because most of
    the people have alot of unread emails that can be a pain point.

    Args:
    num_emails: Number of emails that you want to get.

     Returns:
        List: List of the emails.

    Raises:
        Exception: For errors to get the emails.
    
    Example:
        ```python
        def test_get_emails():
            try:
                num_emails = 10
                emails = get_emails(
                    num_emails=num_emails
                )
                return f'Test case passed: {emails}'
            except Exception as e:
                return f'Error getting emails: {e}'
        ```
    """
    try:
        service= get_service('gmail')
        results = service.users().messages().list(
        userId="me",
        labelIds=["UNREAD", "CATEGORY_PERSONAL"], 
        maxResults= num_emails).execute()
        
        emails= []
        messages = results.get("messages", [])
        if not messages:
            print("No unread messages found.")
            return []
        for msg in messages:
            email= {}
            msg_data = service.users().messages().get(userId="me", id=msg["id"]).execute()
            headers = msg_data["payload"]["headers"]
            subject = sender = ""
            for header in headers:
                if header["name"] == "Subject":
                    subject = header["value"]
                if header["name"] == "From":
                    sender = header["value"]
            email['sender']= sender
            email['subject']= subject
            emails.append(email)
        return emails
    except HttpError as error:
       raise Exception(f"Error: {error}")
    