"""Email service for sending verification and password reset emails."""
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from typing import Optional
import secrets

from shared.config import settings
from shared.logging_config import setup_logging

logger = setup_logging("email_service")


class EmailService:
    """Service for sending emails via configured provider."""
    
    @staticmethod
    def send_email(
        to_email: str,
        subject: str,
        html_content: str,
        text_content: Optional[str] = None
    ) -> bool:
        """Send an email.
        
        Args:
            to_email: Recipient email
            subject: Email subject
            html_content: HTML email body
            text_content: Plain text fallback
            
        Returns:
            True if sent successfully
        """
        provider = settings.email_provider.lower()
        
        try:
            if provider == "smtp":
                return EmailService._send_smtp(to_email, subject, html_content, text_content)
            elif provider == "sendgrid":
                return EmailService._send_sendgrid(to_email, subject, html_content, text_content)
            elif provider == "ses":
                return EmailService._send_ses(to_email, subject, html_content, text_content)
            else:
                logger.error(f"Unknown email provider: {provider}")
                return False
        except Exception as e:
            logger.error(f"Failed to send email: {e}")
            return False
    
    @staticmethod
    def _send_smtp(
        to_email: str,
        subject: str,
        html_content: str,
        text_content: Optional[str]
    ) -> bool:
        """Send email via SMTP."""
        if not settings.smtp_host:
            logger.warning("SMTP not configured, skipping email")
            return False
        
        msg = MIMEMultipart("alternative")
        msg["Subject"] = subject
        msg["From"] = f"{settings.email_from_name} <{settings.email_from}>"
        msg["To"] = to_email
        
        # Add text and HTML parts
        if text_content:
            msg.attach(MIMEText(text_content, "plain"))
        msg.attach(MIMEText(html_content, "html"))
        
        # Send email
        with smtplib.SMTP(settings.smtp_host, settings.smtp_port) as server:
            if settings.smtp_use_tls:
                server.starttls()
            if settings.smtp_username and settings.smtp_password:
                server.login(settings.smtp_username, settings.smtp_password)
            server.send_message(msg)
        
        logger.info(f"Sent email to {to_email} via SMTP")
        return True
    
    @staticmethod
    def _send_sendgrid(
        to_email: str,
        subject: str,
        html_content: str,
        text_content: Optional[str]
    ) -> bool:
        """Send email via SendGrid."""
        try:
            from sendgrid import SendGridAPIClient
            from sendgrid.helpers.mail import Mail
            
            message = Mail(
                from_email=(settings.email_from, settings.email_from_name),
                to_emails=to_email,
                subject=subject,
                html_content=html_content,
                plain_text_content=text_content
            )
            
            sg = SendGridAPIClient(settings.sendgrid_api_key)
            response = sg.send(message)
            
            logger.info(f"Sent email to {to_email} via SendGrid (status: {response.status_code})")
            return True
        except Exception as e:
            logger.error(f"SendGrid error: {e}")
            return False
    
    @staticmethod
    def _send_ses(
        to_email: str,
        subject: str,
        html_content: str,
        text_content: Optional[str]
    ) -> bool:
        """Send email via AWS SES."""
        try:
            import boto3
            
            client = boto3.client(
                'ses',
                region_name=settings.aws_region,
                aws_access_key_id=settings.aws_access_key_id,
                aws_secret_access_key=settings.aws_secret_access_key
            )
            
            body = {"Html": {"Data": html_content}}
            if text_content:
                body["Text"] = {"Data": text_content}
            
            response = client.send_email(
                Source=f"{settings.email_from_name} <{settings.email_from}>",
                Destination={"ToAddresses": [to_email]},
                Message={
                    "Subject": {"Data": subject},
                    "Body": body
                }
            )
            
            logger.info(f"Sent email to {to_email} via SES (ID: {response['MessageId']})")
            return True
        except Exception as e:
            logger.error(f"SES error: {e}")
            return False
    
    @staticmethod
    def send_verification_email(user_email: str, username: str, token: str, base_url: str) -> bool:
        """Send email verification email.
        
        Args:
            user_email: User's email
            username: User's username
            token: Verification token
            base_url: Application base URL
            
        Returns:
            True if sent successfully
        """
        verify_url = f"{base_url}/verify-email?token={token}"
        
        html_content = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; line-height: 1.6; color: #333; }}
                .container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
                .button {{ 
                    display: inline-block; 
                    padding: 12px 24px; 
                    background: #6366f1; 
                    color: white; 
                    text-decoration: none; 
                    border-radius: 6px;
                    margin: 20px 0;
                }}
                .footer {{ margin-top: 30px; font-size: 12px; color: #666; }}
            </style>
        </head>
        <body>
            <div class="container">
                <h2>Welcome to {settings.app_name}!</h2>
                <p>Hi {username},</p>
                <p>Thanks for signing up! Please verify your email address to get started.</p>
                <a href="{verify_url}" class="button">Verify Email Address</a>
                <p>Or copy and paste this link into your browser:</p>
                <p>{verify_url}</p>
                <p>This link will expire in 24 hours.</p>
                <div class="footer">
                    <p>If you didn't create an account, you can safely ignore this email.</p>
                </div>
            </div>
        </body>
        </html>
        """
        
        text_content = f"""
        Welcome to {settings.app_name}!
        
        Hi {username},
        
        Thanks for signing up! Please verify your email address by clicking this link:
        {verify_url}
        
        This link will expire in 24 hours.
        
        If you didn't create an account, you can safely ignore this email.
        """
        
        return EmailService.send_email(
            to_email=user_email,
            subject=f"Verify your {settings.app_name} account",
            html_content=html_content,
            text_content=text_content
        )
    
    @staticmethod
    def send_password_reset_email(user_email: str, username: str, token: str, base_url: str) -> bool:
        """Send password reset email.
        
        Args:
            user_email: User's email
            username: User's username
            token: Reset token
            base_url: Application base URL
            
        Returns:
            True if sent successfully
        """
        reset_url = f"{base_url}/reset-password?token={token}"
        
        html_content = f"""
        <!DOCTYPE html>
        <html>
        <head>
            <style>
                body {{ font-family: Arial, sans-serif; line-height: 1.6; color: #333; }}
                .container {{ max-width: 600px; margin: 0 auto; padding: 20px; }}
                .button {{ 
                    display: inline-block; 
                    padding: 12px 24px; 
                    background: #6366f1; 
                    color: white; 
                    text-decoration: none; 
                    border-radius: 6px;
                    margin: 20px 0;
                }}
                .footer {{ margin-top: 30px; font-size: 12px; color: #666; }}
            </style>
        </head>
        <body>
            <div class="container">
                <h2>Password Reset Request</h2>
                <p>Hi {username},</p>
                <p>We received a request to reset your password. Click the button below to create a new password:</p>
                <a href="{reset_url}" class="button">Reset Password</a>
                <p>Or copy and paste this link into your browser:</p>
                <p>{reset_url}</p>
                <p>This link will expire in 1 hour.</p>
                <div class="footer">
                    <p>If you didn't request a password reset, you can safely ignore this email.</p>
                </div>
            </div>
        </body>
        </html>
        """
        
        text_content = f"""
        Password Reset Request
        
        Hi {username},
        
        We received a request to reset your password. Click this link to create a new password:
        {reset_url}
        
        This link will expire in 1 hour.
        
        If you didn't request a password reset, you can safely ignore this email.
        """
        
        return EmailService.send_email(
            to_email=user_email,
            subject=f"Reset your {settings.app_name} password",
            html_content=html_content,
            text_content=text_content
        )


def generate_token() -> str:
    """Generate a secure random token.
    
    Returns:
        URL-safe token string
    """
    return secrets.token_urlsafe(32)
