"""
Email service for sending notifications related to agency messaging.
"""
from .models import Application
from django.shortcuts import get_object_or_404
import logging
from django.conf import settings
from django.core.mail import EmailMultiAlternatives
from django.utils.html import strip_tags
from django_q.tasks import async_task # Import needed at the top for clarity

logger = logging.getLogger(__name__)
from django.core.mail import send_mail, EmailMultiAlternatives
from django.conf import settings
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from django.contrib.auth import get_user_model
import logging
from .models import Message
logger = logging.getLogger(__name__)
User=get_user_model()

class EmailService:
    """
    Service class for handling email notifications
    """

    def send_email(self, recipient_email, subject, body, html_body=None):
        """
        Send email using Django's send_mail function

        Args:
            recipient_email: Email address to send to
            subject: Email subject
            body: Plain text email body
            html_body: HTML email body (optional)

        Returns:
            dict: Result with success status and error message if failed
        """
        try:
            send_mail(
                subject=subject,
                message=body,
                from_email=getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@kaauh.edu.sa'),
                recipient_list=[recipient_email],
                html_message=html_body,
                fail_silently=False,
            )

            logger.info(f"Email sent successfully to {recipient_email}")
            return {'success': True}

        except Exception as e:
            error_msg = f"Failed to send email to {recipient_email}: {str(e)}"
            logger.error(error_msg)
            return {'success': False, 'error': error_msg}


def send_agency_welcome_email(agency, access_link=None):
    """
    Send welcome email to a new agency with portal access information.

    Args:
        agency: HiringAgency instance
        access_link: AgencyAccessLink instance (optional)

    Returns:
        bool: True if email was sent successfully, False otherwise
    """
    try:
        if not agency.email:
            logger.warning(f"No email found for agency {agency.id}")
            return False

        context = {
            'agency': agency,
            'access_link': access_link,
            'portal_url': getattr(settings, 'AGENCY_PORTAL_URL', 'https://kaauh.edu.sa/portal/'),
        }

        # Render email templates
        html_message = render_to_string('recruitment/emails/agency_welcome.html', context)
        plain_message = strip_tags(html_message)

        # Send email
        send_mail(
            subject='Welcome to KAAUH Recruitment Portal',
            message=plain_message,
            from_email=getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@kaauh.edu.sa'),
            recipient_list=[agency.email],
            html_message=html_message,
            fail_silently=False,
        )

        logger.info(f"Welcome email sent to agency {agency.email}")
        return True

    except Exception as e:
        logger.error(f"Failed to send agency welcome email: {str(e)}")
        return False


def send_assignment_notification_email(assignment, message_type='created'):
    """
    Send email notification about assignment changes.

    Args:
        assignment: AgencyJobAssignment instance
        message_type: Type of notification ('created', 'updated', 'deadline_extended')

    Returns:
        bool: True if email was sent successfully, False otherwise
    """
    try:
        if not assignment.agency.email:
            logger.warning(f"No email found for agency {assignment.agency.id}")
            return False

        context = {
            'assignment': assignment,
            'agency': assignment.agency,
            'job': assignment.job,
            'message_type': message_type,
            'portal_url': getattr(settings, 'AGENCY_PORTAL_URL', 'https://kaauh.edu.sa/portal/'),
        }

        # Render email templates
        html_message = render_to_string('recruitment/emails/assignment_notification.html', context)
        plain_message = strip_tags(html_message)

        # Determine subject based on message type
        subjects = {
            'created': f'New Job Assignment: {assignment.job.title}',
            'updated': f'Assignment Updated: {assignment.job.title}',
            'deadline_extended': f'Deadline Extended: {assignment.job.title}',
        }
        subject = subjects.get(message_type, f'Assignment Notification: {assignment.job.title}')

        # Send email
        send_mail(
            subject=subject,
            message=plain_message,
            from_email=getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@kaauh.edu.sa'),
            recipient_list=[assignment.agency.email],
            html_message=html_message,
            fail_silently=False,
        )

        logger.info(f"Assignment notification email sent to {assignment.agency.email} for {message_type}")
        return True

    except Exception as e:
        logger.error(f"Failed to send assignment notification email: {str(e)}")
        return False


def send_interview_invitation_email(candidate, job, meeting_details=None, recipient_list=None):
    """
    Send interview invitation email using HTML template.

    Args:
        candidate: Candidate instance
        job: Job instance
        meeting_details: Dictionary with meeting information (optional)
        recipient_list: List of additional email addresses (optional)

    Returns:
        dict: Result with success status and error message if failed
    """
    try:
        # Prepare recipient list
        recipients = []
        if candidate.hiring_source == "Agency":
            try:
                recipients.append(candidate.hiring_agency.email)
            except :
                pass
        else:
            recipients.append(candidate.email)

        if recipient_list:
            recipients.extend(recipient_list)


        if not recipients:
            return {'success': False, 'error': 'No recipient email addresses provided'}

        # Prepare context for template
        context = {
            'candidate_name': candidate.full_name or candidate.name,
            'candidate_email': candidate.email,
            'candidate_phone': candidate.phone or '',
            'job_title': job.title,
            'department': getattr(job, 'department', ''),
            'company_name': getattr(settings, 'COMPANY_NAME', 'Norah University'),
        }

        # Add meeting details if provided
        if meeting_details:
            context.update({
                'meeting_topic': meeting_details.get('topic', f'Interview for {job.title}'),
                'meeting_date_time': meeting_details.get('date_time', ''),
                'meeting_duration': meeting_details.get('duration', '60 minutes'),
                'join_url': meeting_details.get('join_url', ''),
            })

        # Render HTML template
        html_message = render_to_string('emails/interview_invitation.html', context)
        plain_message = strip_tags(html_message)

        # Create email with both HTML and plain text versions
        email = EmailMultiAlternatives(
            subject=f'Interview Invitation: {job.title}',
            body=plain_message,
            from_email=getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@kaauh.edu.sa'),
            to=recipients,
        )
        email.attach_alternative(html_message, "text/html")

        # Send email
        email.send(fail_silently=False)

        logger.info(f"Interview invitation email sent successfully to {', '.join(recipients)}")
        return {
            'success': True,
            'recipients_count': len(recipients),
            'message': f'Interview invitation sent successfully to {len(recipients)} recipient(s)'
        }

    except Exception as e:
        error_msg = f"Failed to send interview invitation email: {str(e)}"
        logger.error(error_msg, exc_info=True)
        return {'success': False, 'error': error_msg}





def send_bulk_email(subject, message, recipient_list, request=None, attachments=None, async_task_=False, from_interview=False,job=None):
    """
    Send bulk email to multiple recipients with HTML support and attachments,
    supporting synchronous or asynchronous dispatch.
    """

    # --- 1. Categorization and Custom Message Preparation (CORRECTED) ---
    if not from_interview:

        agency_emails = []
        pure_candidate_emails = []
        candidate_through_agency_emails = []

        if not recipient_list:
            return {'success': False, 'error': 'No recipients provided'}

        # This must contain (final_recipient_email, customized_message) for ALL sends
        customized_sends = []

        # 1a. Classify Recipients and Prepare Custom Messages
        for email in recipient_list:
            email = email.strip().lower()

            try:
                candidate = get_object_or_404(Application, person__email=email)
            except Exception:
                logger.warning(f"Candidate not found for email: {email}")
                continue

            candidate_name = candidate.person.full_name


            # --- Candidate belongs to an agency (Final Recipient: Agency) ---
            if candidate.hiring_agency and candidate.hiring_agency.email:
                agency_email = candidate.hiring_agency.email
                agency_message = f"Hi, {candidate_name}" + "\n" + message

                # Add Agency email as the recipient with the custom message
                customized_sends.append((agency_email, agency_message))
                agency_emails.append(agency_email)
                candidate_through_agency_emails.append(candidate.email) # For sync block only

            # --- Pure Candidate (Final Recipient: Candidate) ---
            else:
                candidate_message = f"Hi, {candidate_name}" + "\n" + message

                # Add Candidate email as the recipient with the custom message
                customized_sends.append((email, candidate_message))
                pure_candidate_emails.append(email) # For sync block only

        # Calculate total recipients based on the size of the final send list
        total_recipients = len(customized_sends)

        if total_recipients == 0:
            return {'success': False, 'error': 'No valid recipients found for sending.'}
    else:
        # For interview flow
        total_recipients = len(recipient_list)


    # --- 2. Handle ASYNC Dispatch (FIXED: Single loop used) ---
    if async_task_:
        try:

            processed_attachments = attachments if attachments else []
            task_ids = []

            job_id=job.id
            sender_user_id=request.user.id if request and hasattr(request, 'user') and request.user.is_authenticated else None
            if not from_interview:
                # Loop through ALL final customized sends
                for recipient_email, custom_message in customized_sends:
                    task_id = async_task(
                        'recruitment.tasks.send_bulk_email_task',
                        subject,
                        custom_message, # Pass the custom message
                        [recipient_email], # Pass the specific recipient as a list of one
                        processed_attachments,
                        sender_user_id,
                        job_id,
                        hook='recruitment.tasks.email_success_hook',
 
                    )
                    task_ids.append(task_id)

                logger.info(f"{len(task_ids)} tasks ({total_recipients} emails) queued.")

                return {
                    'success': True,
                    'async': True,
                    'task_ids': task_ids,
                    'message': f'Emails queued for background sending to {len(task_ids)} recipient(s).'
                }

            else: # from_interview is True (generic send to all participants)
                 task_id = async_task(
                        'recruitment.tasks.send_bulk_email_task',
                        subject,
                        message,
                        recipient_list, # Send the original message to the entire list
                        processed_attachments,
                        hook='recruitment.tasks.email_success_hook'
                    )
                 task_ids.append(task_id)
                 logger.info(f"Interview emails queued. ID: {task_id}")

                 return {
                    'success': True,
                    'async': True,
                    'task_ids': task_ids,
                    'message': f'Interview emails queued for background sending to {total_recipients} recipient(s)'
                }


        except ImportError:
            logger.error("Async execution requested, but django_q or required modules not found. Defaulting to sync.")
            async_task_ = False
        except Exception as e:
            logger.error(f"Failed to queue async tasks: {str(e)}", exc_info=True)
            return {'success': False, 'error': f"Failed to queue async tasks: {str(e)}"}

    else:
    # --- 3. Handle SYNCHRONOUS Send (No changes needed here, as it was fixed previously) ---
        try:
            # NOTE: The synchronous block below should also use the 'customized_sends'
            # list for consistency instead of rebuilding messages from 'pure_candidate_emails'
            # and 'agency_emails', but keeping your current logic structure to minimize changes.

            from_email = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@kaauh.edu.sa')
            is_html = '<' in message and '>' in message
            successful_sends = 0

            # Helper Function for Sync Send (as provided)
            def send_individual_email(recipient, body_message):
                # ... (Existing helper function logic) ...
                nonlocal successful_sends

                if is_html:
                    plain_message = strip_tags(body_message)
                    email_obj = EmailMultiAlternatives(subject=subject, body=plain_message, from_email=from_email, to=[recipient])
                    email_obj.attach_alternative(body_message, "text/html")
                else:
                    email_obj = EmailMultiAlternatives(subject=subject, body=body_message, from_email=from_email, to=[recipient])

                if attachments:
                    for attachment in attachments:
                        if hasattr(attachment, 'read'):
                            filename = getattr(attachment, 'name', 'attachment')
                            content = attachment.read()
                            content_type = getattr(attachment, 'content_type', 'application/octet-stream')
                            email_obj.attach(filename, content, content_type)
                        elif isinstance(attachment, tuple) and len(attachment) == 3:
                            filename, content, content_type = attachment
                            email_obj.attach(filename, content, content_type)

                try:
                    email_obj.send(fail_silently=False)
                    successful_sends += 1
                except Exception as e:
                    logger.error(f"Failed to send email to {recipient}: {str(e)}", exc_info=True)

            if not from_interview:
                # Send Emails - Pure Candidates
                for email in pure_candidate_emails:
                    candidate_name = Application.objects.filter(email=email).first().first_name
                    candidate_message = f"Hi, {candidate_name}" + "\n" + message
                    send_individual_email(email, candidate_message)

                # Send Emails - Agencies
                i = 0
                for email in agency_emails:
                    candidate_email = candidate_through_agency_emails[i]
                    candidate_name = Application.objects.filter(email=candidate_email).first().first_name
                    agency_message = f"Hi, {candidate_name}" + "\n" + message
                    send_individual_email(email, agency_message)
                    i += 1

                logger.info(f"Bulk email processing complete. Sent successfully to {successful_sends} out of {total_recipients} unique recipients.")
                return {
                    'success': True,
                    'recipients_count': successful_sends,
                    'message': f'Email processing complete. {successful_sends} email(s) were sent successfully to {total_recipients} unique intended recipients.'
                }
            else:
                for email in recipient_list:
                    send_individual_email(email, message)

                logger.info(f"Interview email processing complete. Sent successfully to {successful_sends} out of {total_recipients} recipients.")
                return {
                    'success': True,
                    'recipients_count': successful_sends,
                    'message': f'Interview emails sent successfully to {successful_sends} recipient(s).'
                }

        except Exception as e:
            error_msg = f"Failed to process bulk email send request: {str(e)}"
            logger.error(error_msg, exc_info=True)
            return {'success': False, 'error': error_msg}