"""
Email service for contact form notifications.
Production-ready with retry logic and comprehensive error handling.
"""
from django.core.mail import EmailMultiAlternatives, get_connection
from django.template.loader import render_to_string
from django.conf import settings
from django.utils.html import strip_tags
from django.core.mail.backends.smtp import EmailBackend
import logging
import time
from typing import Optional, List

logger = logging.getLogger(__name__)


def _send_email_with_retry(email_message, max_retries: int = 3, delay: float = 1.0) -> bool:
    """
    Send email with retry logic for production reliability.
    
    Args:
        email_message: EmailMultiAlternatives instance
        max_retries: Maximum number of retry attempts
        delay: Delay between retries in seconds
        
    Returns:
        bool: True if email was sent successfully, False otherwise
    """
    for attempt in range(max_retries + 1):
        try:
            # Test connection before sending
            connection = get_connection()
            connection.open()
            connection.close()
            
            # Send the email
            email_message.send()
            return True
            
        except Exception as e:
            logger.warning(f"Email send attempt {attempt + 1} failed: {str(e)}")
            
            if attempt < max_retries:
                time.sleep(delay * (2 ** attempt))  # Exponential backoff
                continue
            else:
                logger.error(f"Failed to send email after {max_retries + 1} attempts: {str(e)}")
                return False
    
    return False


def _create_email_connection() -> Optional[EmailBackend]:
    """
    Create a robust email connection with production settings.
    
    Returns:
        EmailBackend instance or None if connection fails
    """
    try:
        connection = get_connection(
            host=settings.EMAIL_HOST,
            port=settings.EMAIL_PORT,
            username=settings.EMAIL_HOST_USER,
            password=settings.EMAIL_HOST_PASSWORD,
            use_tls=settings.EMAIL_USE_TLS,
            use_ssl=settings.EMAIL_USE_SSL,
            timeout=getattr(settings, 'EMAIL_TIMEOUT', 30),
            connection_timeout=getattr(settings, 'EMAIL_CONNECTION_TIMEOUT', 10),
            read_timeout=getattr(settings, 'EMAIL_READ_TIMEOUT', 10),
        )
        
        # Test the connection
        connection.open()
        connection.close()
        
        return connection
        
    except Exception as e:
        logger.error(f"Failed to create email connection: {str(e)}")
        return None


def send_contact_submission_notification(submission):
    """
    Send email notification for new contact form submission.
    
    Args:
        submission: ContactSubmission instance
        
    Returns:
        bool: True if email was sent successfully, False otherwise
    """
    try:
        # Get company email from settings
        company_email = getattr(settings, 'COMPANY_EMAIL', None)
        if not company_email:
            logger.warning("COMPANY_EMAIL not configured in settings")
            return False
        
        # Prepare email context
        context = {
            'submission': submission,
            'logo_url': f'{settings.SITE_URL}/images/logo.png',
            'site_url': settings.SITE_URL,
        }
        
        # Render email templates
        html_content = render_to_string(
            'contact/contact_submission_email.html',
            context
        )
        text_content = render_to_string(
            'contact/contact_submission_email.txt',
            context
        )
        
        # Create email subject with priority indicator
        priority_emoji = {
            'urgent': '🚨',
            'high': '⚠️',
            'medium': '📋',
            'low': '📝'
        }.get(submission.priority, '📋')
        
        subject = f"{priority_emoji} New Contact Form Submission - {submission.company} (#{submission.id})"
        
        # Create email message
        email = EmailMultiAlternatives(
            subject=subject,
            body=text_content,
            from_email=settings.DEFAULT_FROM_EMAIL,
            to=[company_email],
            reply_to=[submission.email]  # Allow direct reply to customer
        )
        
        # Add headers for better email handling
        email.extra_headers = {
            'X-Priority': '1' if submission.priority in ['urgent', 'high'] else '3',
            'X-MSMail-Priority': 'High' if submission.priority in ['urgent', 'high'] else 'Normal',
        }
        
        # Attach HTML version
        email.attach_alternative(html_content, "text/html")
        
        # Send email with retry logic
        success = _send_email_with_retry(email)
        
        if success:
            logger.info(f"Contact submission notification sent for submission #{submission.id}")
        else:
            logger.error(f"Failed to send contact submission notification for submission #{submission.id} after retries")
        
        return success
        
    except Exception as e:
        logger.error(f"Failed to send contact submission notification for submission #{submission.id}: {str(e)}")
        return False


def send_contact_submission_confirmation(submission):
    """
    Send confirmation email to the customer who submitted the form.
    
    Args:
        submission: ContactSubmission instance
        
    Returns:
        bool: True if email was sent successfully, False otherwise
    """
    try:
        # Prepare email context
        context = {
            'submission': submission,
            'logo_url': f'{settings.SITE_URL}/images/logo.png',
            'site_url': settings.SITE_URL,
        }
        
        # Create confirmation email
        subject = "Thank you for contacting GNX Software Solutions"
        
        # Render HTML email template
        html_content = render_to_string(
            'contact/contact_submission_confirmation.html',
            context
        )
        
        # Render text email template
        text_content = render_to_string(
            'contact/contact_submission_confirmation.txt',
            context
        )
        
        # Create email message
        email = EmailMultiAlternatives(
            subject=subject,
            body=text_content,
            from_email=settings.DEFAULT_FROM_EMAIL,
            to=[submission.email]
        )
        
        # Attach HTML version
        email.attach_alternative(html_content, "text/html")
        
        # Send email with retry logic
        success = _send_email_with_retry(email)
        
        if success:
            logger.info(f"Contact submission confirmation sent to {submission.email} for submission #{submission.id}")
        else:
            logger.error(f"Failed to send contact submission confirmation for submission #{submission.id} after retries")
        
        return success
        
    except Exception as e:
        logger.error(f"Failed to send contact submission confirmation for submission #{submission.id}: {str(e)}")
        return False


def check_email_health() -> dict:
    """
    Check email service health for production monitoring.
    
    Returns:
        dict: Health status information
    """
    health_status = {
        'email_service': 'unknown',
        'connection_test': False,
        'configuration_valid': False,
        'error_message': None
    }
    
    try:
        # Check configuration
        required_settings = [
            'EMAIL_HOST', 'EMAIL_PORT', 'EMAIL_HOST_USER', 
            'EMAIL_HOST_PASSWORD', 'DEFAULT_FROM_EMAIL', 'COMPANY_EMAIL'
        ]
        
        missing_settings = []
        for setting in required_settings:
            if not getattr(settings, setting, None):
                missing_settings.append(setting)
        
        if missing_settings:
            health_status['error_message'] = f"Missing email settings: {', '.join(missing_settings)}"
            return health_status
        
        health_status['configuration_valid'] = True
        
        # Test connection
        connection = _create_email_connection()
        if connection:
            health_status['connection_test'] = True
            health_status['email_service'] = 'healthy'
        else:
            health_status['email_service'] = 'unhealthy'
            health_status['error_message'] = 'Failed to establish email connection'
            
    except Exception as e:
        health_status['email_service'] = 'error'
        health_status['error_message'] = str(e)
    
    return health_status


def send_test_email(to_email: str) -> bool:
    """
    Send a test email to verify email configuration.
    
    Args:
        to_email: Email address to send test email to
        
    Returns:
        bool: True if test email was sent successfully
    """
    try:
        subject = "GNX Email Service Test"
        message = f"""
This is a test email from the GNX contact form system.

If you receive this email, the email service is working correctly.

Timestamp: {time.strftime("%Y-%m-%d %H:%M:%S UTC")}
        """
        
        email = EmailMultiAlternatives(
            subject=subject,
            body=message,
            from_email=settings.DEFAULT_FROM_EMAIL,
            to=[to_email]
        )
        
        success = _send_email_with_retry(email)
        
        if success:
            logger.info(f"Test email sent successfully to {to_email}")
        else:
            logger.error(f"Failed to send test email to {to_email}")
            
        return success
        
    except Exception as e:
        logger.error(f"Error sending test email to {to_email}: {str(e)}")
        return False
