from typing import Optional, List, Union
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
import base64
import os
import logging

logger = logging.getLogger("gmail_mcp")


def send_email(
    service,
    to: Union[str, List[str]],
    subject: str,
    message_text: str,
    html_content: Optional[str] = None,
    cc: Optional[Union[str, List[str]]] = None,
    bcc: Optional[Union[str, List[str]]] = None,
    attachment_paths: Optional[List[str]] = None
) -> dict:
    """
    Send an email using Gmail API.

    Args:
        service: Gmail API service instance
        to: Email address or list of addresses to send to
        subject: Email subject
        message_text: Plain text message content
        html_content: HTML version of the message (optional)
        cc: Email address or list of addresses to CC
        bcc: Email address or list of addresses to BCC
        attachment_paths: List of file paths to attach

    Returns:
        dict: API response containing sent message details

    Raises:
        HttpError: If the API request fails
    """
    try:
        # Create message container
        message = MIMEMultipart('alternative')
        message['Subject'] = subject

        # Handle multiple recipients
        if isinstance(to, list):
            message['To'] = ', '.join(to)
        else:
            message['To'] = to

        # Handle CC recipients
        if cc:
            if isinstance(cc, list):
                message['Cc'] = ', '.join(cc)
            else:
                message['Cc'] = cc

        # Handle BCC recipients
        if bcc:
            if isinstance(bcc, list):
                message['Bcc'] = ', '.join(bcc)
            else:
                message['Bcc'] = bcc

        # Add plain text version
        part1 = MIMEText(message_text, 'plain')
        message.attach(part1)

        # Add HTML version if provided
        if html_content:
            part2 = MIMEText(html_content, 'html')
            message.attach(part2)

        # Add attachments if provided
        if attachment_paths:
            for file_path in attachment_paths:
                if os.path.exists(file_path):
                    with open(file_path, 'rb') as attachment:
                        part = MIMEBase('application', 'octet-stream')
                        part.set_payload(attachment.read())

                    # Encode the attachment
                    encoders.encode_base64(part)

                    # Add header
                    filename = os.path.basename(file_path)
                    part.add_header(
                        'Content-Disposition',
                        f'attachment; filename= {filename}'
                    )

                    message.attach(part)

        # Encode the message for sending
        raw_message = base64.urlsafe_b64encode(
            message.as_bytes()).decode('utf-8')

        # Send the email
        sent_message = service.users().messages().send(
            userId='me',
            body={'raw': raw_message}
        ).execute()

        return sent_message

    except HttpError as error:
        logger.error(f"An error occurred: {error}")
        raise error


# Example usage:
"""
# Initialize your Gmail API service first
service = build('gmail', 'v1', credentials=creds)

# Simple text email
response = send_email(
    service=service,
    to='recipient@example.com',
    subject='Hello from Gmail API',
    message_text='This is a test email sent using the Gmail API.'
)

# HTML email with attachment
response = send_email(
    service=service,
    to=['recipient1@example.com', 'recipient2@example.com'],
    subject='Test Email with Attachment',
    message_text='Please see the attached file.',
    html_content='<h1>Hello</h1><p>Please see the attached file.</p>',
    cc='cc@example.com',
    bcc=['bcc1@example.com', 'bcc2@example.com'],
    attachment_paths=['/path/to/file.pdf', '/path/to/image.jpg']
)

print(f"Message Id: {response['id']}")
"""
