from django.core.mail import EmailMultiAlternatives, get_connection
from django.template.loader import render_to_string
from django.conf import settings
import logging
import time

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.
    Uses Django settings from .env file.
    
    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 (uses EMAIL_BACKEND from settings)
            connection = get_connection()
            connection.open()
            connection.close()
            
            # Send the email (uses EMAIL_BACKEND and credentials from settings)
            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


class CareerEmailService:
    """Service for handling career-related emails"""
    
    def send_application_confirmation(self, application):
        """
        Send confirmation email to applicant
        """
        try:
            subject = f"Application Received - {application.job.title}"
            from_email = settings.DEFAULT_FROM_EMAIL
            to_email = [application.email]
            
            # Create context for email template
            context = {
                'applicant_name': application.full_name,
                'job_title': application.job.title,
                'job_location': application.job.location,
                'application_date': application.applied_date,
                'logo_url': f'{settings.SITE_URL}/images/logo.png',
                'site_url': settings.SITE_URL,
            }
            
            # Render email templates
            text_content = render_to_string('career/application_confirmation.txt', context)
            html_content = render_to_string('career/application_confirmation.html', context)
            
            # Create email (uses DEFAULT_FROM_EMAIL from settings)
            email = EmailMultiAlternatives(
                subject=subject,
                body=text_content,
                from_email=from_email,  # Uses settings.DEFAULT_FROM_EMAIL
                to=to_email
            )
            email.attach_alternative(html_content, "text/html")
            
            # Send email with retry logic (uses EMAIL_BACKEND and credentials from settings)
            success = _send_email_with_retry(email)
            
            if success:
                logger.info(f"Confirmation email sent to {application.email}")
            else:
                logger.error(f"Failed to send confirmation email to {application.email} after retries")
            return success
            
        except Exception as e:
            logger.error(f"Failed to send confirmation email: {str(e)}", exc_info=True)
            return False
    
    def send_application_notification_to_admin(self, application):
        """
        Send notification email to company about new application
        """
        try:
            subject = f"New Job Application: {application.job.title} - {application.full_name}"
            from_email = settings.DEFAULT_FROM_EMAIL
            to_email = [settings.COMPANY_EMAIL]
            
            # Create context for email template
            context = {
                'applicant_name': application.full_name,
                'applicant_email': application.email,
                'applicant_phone': application.phone,
                'job_title': application.job.title,
                'current_position': application.current_position,
                'current_company': application.current_company,
                'years_of_experience': application.years_of_experience,
                'cover_letter': application.cover_letter,
                'portfolio_url': application.portfolio_url,
                'linkedin_url': application.linkedin_url,
                'github_url': application.github_url,
                'website_url': application.website_url,
                'expected_salary': application.expected_salary,
                'salary_currency': application.salary_currency,
                'available_from': application.available_from,
                'notice_period': application.notice_period,
                'application_date': application.applied_date,
                'resume_url': application.resume.url if application.resume else None,
                'logo_url': f'{settings.SITE_URL}/images/logo.png',
                'site_url': settings.SITE_URL,
            }
            
            # Render email templates
            text_content = render_to_string('career/application_notification.txt', context)
            html_content = render_to_string('career/application_notification.html', context)
            
            # Create email (uses DEFAULT_FROM_EMAIL and COMPANY_EMAIL from settings)
            email = EmailMultiAlternatives(
                subject=subject,
                body=text_content,
                from_email=from_email,  # Uses settings.DEFAULT_FROM_EMAIL
                to=to_email,  # Uses settings.COMPANY_EMAIL
                reply_to=[application.email]
            )
            email.attach_alternative(html_content, "text/html")
            
            # Attach resume if available
            if application.resume:
                email.attach_file(application.resume.path)
            
            # Send email with retry logic (uses EMAIL_BACKEND and credentials from settings)
            success = _send_email_with_retry(email)
            
            if success:
                logger.info(f"Admin notification email sent for application from {application.email}")
            else:
                logger.error(f"Failed to send admin notification email for application from {application.email} after retries")
            return success
            
        except Exception as e:
            logger.error(f"Failed to send admin notification email: {str(e)}", exc_info=True)
            return False

