import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import boto3
from typing import Optional, List
import re  # Simple URL detection for nicer links in success emails

class EmailService:
    def __init__(self):
        self.ssm = boto3.client('ssm')
        self._initialize_config()

    def _initialize_config(self):
        """Initialize email configuration from SSM Parameter Store"""
        try:
            self.gmail_user = self._get_parameter('/gmail/username')
            self.gmail_password = self._get_parameter('/gmail/app_password')
            self.from_email = self.gmail_user
            # Default to_emails (internal)
            to_emails_str = self._get_parameter('/gmail/to_emails')
            self.to_emails = [email.strip() for email in to_emails_str.split(',')]
            # Client emails will be loaded on demand
        except Exception as e:
            print(f"Failed to initialize email configuration: {str(e)}")
            raise

    def _get_parameter(self, name: str) -> str:
        """Get a parameter from AWS SSM Parameter Store"""
        response = self.ssm.get_parameter(
            Name=name,
            WithDecryption=True
        )
        return response['Parameter']['Value']

    def send_notification(self, date: str, status: str, error_message: Optional[str] = None, client_email: bool = False, process_name: str = "Task Status Update") -> Optional[str]:
        """
        Send an email notification about process status update completion or failure using Gmail SMTP.
        Args:
            date (str): The week start date for which the process update was performed
            status (str): Either 'success' or 'error'
            error_message (Optional[str]): Error message if status is 'error'
            client_email (bool): If True, send to client recipients and add client indicator
            process_name (str): The name of the process (used in subject and body)
        Returns:
            Optional[str]: Message ID if successful, None if failed
        """
        try:
            # Select recipients
            if client_email:
                to_emails_str = self._get_parameter('/gmail/to_emails_client')
                to_emails = [email.strip() for email in to_emails_str.split(',')]
            else:
                to_emails = self.to_emails

            # Validate email addresses
            if not to_emails:
                raise ValueError("No recipient emails configured")
            if not all('@' in email for email in to_emails):
                raise ValueError("Invalid email address format in recipients")

            # Create message container
            msg = MIMEMultipart('alternative')
            msg['Subject'] = f"{process_name} Complete" if status == 'success' else f"{process_name} Failed"
            msg['From'] = self.from_email
            msg['To'] = ', '.join(to_emails)

            client_indicator = "<div style='color: #007bff; font-weight: bold;'>This is a notification email.</div>" if client_email else ""

            if status == 'success':
                # Treat error_message as an optional "details" field for success (e.g., report links)
                details_html = ""
                if error_message:
                    message_text = str(error_message)
                    # If a URL is present, show a short, friendly download link instead of the full URL
                    url_match = re.search(r'(https?://\S+)', message_text)
                    if url_match:
                        url = url_match.group(1)
                        details_html = (
                            "<p style='margin-top: 10px;'>"
                            "Combined weekly report generated successfully. "
                            f"<a href='{url}'>Download report</a>"
                            "</p>"
                        )
                    else:
                        # Fallback: show full text, safely escaped
                        safe_details = (
                            message_text
                            .replace('&', '&amp;')
                            .replace('<', '&lt;')
                            .replace('>', '&gt;')
                        )
                        details_html = f"<p style='margin-top: 10px; white-space: pre-wrap;'>{safe_details}</p>"

                html_content = f"""
                {client_indicator}
                <div style=\"font-family: Arial, sans-serif; padding: 20px;\">
                    <h2 style=\"color: #28a745;\">✅ {process_name} Successful</h2>
                    <p>The {process_name.lower()} has been completed successfully.</p>
                    {details_html}
                </div>
                """
            else:
                # For client emails, do not include stack trace
                if client_email and error_message:
                    # Only keep the first two lines (error type and error message)
                    error_details = "\n".join(error_message.split("\n")[:2])
                else:
                    error_details = error_message if error_message else f"An error occurred during the {process_name.lower()}."
                html_content = f"""
                {client_indicator}
                <div style=\"font-family: Arial, sans-serif; padding: 20px;\">
                    <h2 style=\"color: #dc3545;\">❌ {process_name} Failed</h2>
                    <p>The {process_name.lower()} has failed.</p>
                    <div style=\"background-color: #f8f9fa; padding: 15px; border-radius: 5px; margin-top: 15px;\">
                        <h3 style=\"color: #dc3545; margin-top: 0;\">Error Details:</h3>
                        <pre style=\"white-space: pre-wrap; word-wrap: break-word;\">{error_details}</pre>
                    </div>
                </div>
                """

            # Attach HTML content
            msg.attach(MIMEText(html_content, 'html'))

            # Connect to Gmail's SMTP server
            with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp_server:
                smtp_server.login(self.gmail_user, self.gmail_password)
                smtp_server.send_message(msg)
                
            return msg['Message-ID']
        except Exception as e:
            print(f"Failed to send email: {str(e)}")
            return None

# Create a singleton instance
email_service = EmailService() 