from django.core.mail import get_connection, EmailMultiAlternatives, EmailMessage
from django.template.loader import render_to_string
from django.utils.html import strip_tags
from django.conf import settings
import re
from rest_framework.response import Response
from rest_framework import status
from rest_framework.exceptions import NotFound
from Settings.models import SMTPSettings
from Establishment.models import Establishment  # Importer le modèle Establishment
import logging

# Ajouter un logger pour debug
logger = logging.getLogger(__name__)

def getConnection(id_establishement):
    try:
        # Récupérer l'instance de l'établissement
        establishment = Establishment.objects.get(id=id_establishement)
        logger.info(f"Establishment trouvé: {establishment.name} (ID: {id_establishement})")

        try:
            # Récupérer les paramètres SMTP associés à l'établissement
            smtp_settings = SMTPSettings.objects.get(establishment=establishment)
            logger.info(f"Paramètres SMTP trouvés pour {establishment.name}: {smtp_settings.smtp_server}:{smtp_settings.smtp_port}")

            # Créer une connexion SMTP avec les paramètres récupérés
            connection = get_connection(
                host=smtp_settings.smtp_server,
                port=smtp_settings.smtp_port,
                username=smtp_settings.smtp_user,
                password=smtp_settings.smtp_password,
                use_tls=smtp_settings.use_tls,
                use_ssl=smtp_settings.use_ssl
            )
            return connection
        except SMTPSettings.DoesNotExist:
            logger.warning(f"Aucun paramètre SMTP spécifique trouvé pour l'établissement {establishment.name} (ID: {id_establishement})")
            # Aucun paramètre SMTP spécifique, retournera None
            return None
    except Establishment.DoesNotExist:
        logger.error(f"Aucun établissement trouvé avec l'ID {id_establishement}")
        raise NotFound(f"Aucun établissement trouvé avec l'ID {id_establishement}")

def sendMail(subject, message, recipients, cc=[], bcc=[], attachments=[], connection=None):
    try:
        # S'assurer que recipients, cc, bcc sont des listes
        if isinstance(recipients, str):
            recipients = [recipients]
        if isinstance(cc, str):
            cc = [cc]
        if isinstance(bcc, str):
            bcc = [bcc]

        # Récupération robuste du username
        username = getattr(connection, 'username', None)

        plain_message = strip_tags(message)
        if connection is not None:
            from_email = username
            logger.info(f"Utilisation de la connexion SMTP spécifique: {username}")
        else:
            from_email = settings.EMAIL_HOST_USER
            logger.info(f"Utilisation de la configuration SMTP par défaut: {from_email}")

        logger.info(f"From email: {from_email}")
        logger.info(f"Configuration par défaut - Host: {settings.EMAIL_HOST}, Port: {settings.EMAIL_PORT}, Use TLS: {settings.EMAIL_USE_TLS}")

        email = EmailMultiAlternatives(
            subject=subject,
            body=plain_message,
            from_email=from_email,
            to=recipients,
            cc=cc,
            bcc=bcc,
            connection=connection
        )
        email.attach_alternative(message, "text/html")

        for attachment in attachments:
            email.attach(*attachment)

        logger.info("Tentative d'envoi de l'email...")
        email.send(fail_silently=False)
        logger.info("Email envoyé avec succès !")
        return Response({'message': 'Email envoyé avec succès.'}, status=status.HTTP_200_OK)
    except Exception as e:
        logger.error(f"Erreur lors de l'envoi de l'email: {str(e)}")
        logger.error(f"Settings : {connection}")
        logger.error(f"Settings : {connection}")
        logger.error(f"Type d'erreur: {type(e)}")
        import traceback
        logger.error(f"Traceback: {traceback.format_exc()}")
        return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

def envoieReinitMotDePasse(recipients, code):
    errorMessage = ''
    try:
        EMAIL_REINIT_SUBJECT = 'Réinitialisation du mot de passe'
        context = {
            'BASE_URL': settings.BASE_URL,
            'code': str(code)
        }
        subject = EMAIL_REINIT_SUBJECT
        html_message  = render_to_string('emails/resetPassword.html', context)
        sendMail(subject=subject, message=html_message, recipients=recipients)

    except Exception as e:
        errorMessage = str(e)

    return errorMessage

def sendRegistrationDirector(recipients, establishment_id):
    errorMessage = ''
    try:
        # Préparation du contexte pour le template
        EMAIL_INSCRIPTION_SUBJECT = '[N3WT-SCHOOL] Bienvenue dans la communauté !'
        context = {
            'BASE_URL': settings.BASE_URL,
            'URL_DJANGO': settings.URL_DJANGO,
            'email': recipients,
            'establishment': establishment_id
        }
        subject = EMAIL_INSCRIPTION_SUBJECT
        html_message  = render_to_string('emails/subscribeDirector.html', context)
        sendMail(subject=subject, message=html_message, recipients=recipients)


    except Exception as e:
        errorMessage = str(e)

    return errorMessage


def sendRegisterForm(recipients, establishment_id):
    errorMessage = ''
    try:
        # Préparation du contexte pour le template
        EMAIL_INSCRIPTION_SUBJECT = '[N3WT-SCHOOL] Dossier Inscription'
        context = {
            'BASE_URL': settings.BASE_URL,
            'email': recipients,
            'establishment': establishment_id
        }
        # Récupérer la connexion SMTP
        connection = getConnection(establishment_id)
        subject = EMAIL_INSCRIPTION_SUBJECT
        html_message  = render_to_string('emails/inscription.html', context)
        sendMail(subject=subject, message=html_message, recipients=recipients, connection=connection)


    except Exception as e:
        errorMessage = str(e)

    return errorMessage

def sendMandatSEPA(recipients, establishment_id):
    errorMessage = ''
    try:
        # Préparation du contexte pour le template
        EMAIL_INSCRIPTION_SUBJECT = '[N3WT-SCHOOL] Mandat de prélèvement SEPA'
        context = {
            'BASE_URL': settings.BASE_URL,
            'email': recipients,
            'establishment': establishment_id
        }

        # Récupérer la connexion SMTP
        connection = getConnection(establishment_id)
        subject = EMAIL_INSCRIPTION_SUBJECT
        html_message  = render_to_string('emails/sepa.html', context)
        sendMail(subject=subject, message=html_message, recipients=recipients, connection=connection)

    except Exception as e:
        errorMessage = str(e)

    return errorMessage

def envoieRelanceDossierInscription(recipients, code):
    EMAIL_RELANCE_SUBJECT = '[N3WT-SCHOOL] Relance - Dossier Inscription'
    EMAIL_RELANCE_CORPUS = 'Bonjour,\nN\'ayant pas eu de retour de votre part, nous vous renvoyons le lien vers le formulaire d\'inscription : ' + BASE_URL + '/users/login\nCordialement'
    errorMessage = ''
    try:
        sendMail(EMAIL_RELANCE_SUBJECT, EMAIL_RELANCE_CORPUS%str(code), recipients)

    except Exception as e:
        errorMessage = str(e)

    return errorMessage

def isValid(message, fiche_inscription):
    # Est-ce que la référence du dossier est VALIDATED
    subject = message.subject
    print ("++++ " + subject)
    responsableMail = message.from_header
    result = re.search('<(.*)>', responsableMail)

    if result:
        responsableMail = result.group(1)

    result = re.search(r'.*\[Ref(.*)\].*', subject)
    idMail = -1
    if result:
        idMail = result.group(1).strip()

    eleve = fiche_inscription.eleve
    responsable = eleve.getMainGuardian()
    mailReponsableAVerifier = responsable.mail

    return responsableMail == mailReponsableAVerifier and str(idMail) == str(fiche_inscription.eleve.id)

def sendRegisterTeacher(recipients, establishment_id):
    errorMessage = ''
    try:
        EMAIL_INSCRIPTION_SUBJECT = '[N3WT-SCHOOL] Bienvenue sur N3wt School (Enseignant)'
        context = {
            'BASE_URL': settings.BASE_URL,
            'URL_DJANGO': settings.URL_DJANGO,
            'email': recipients,
            'establishment': establishment_id
        }
        connection = getConnection(establishment_id)
        subject = EMAIL_INSCRIPTION_SUBJECT
        html_message  = render_to_string('emails/inscription_teacher.html', context)
        sendMail(subject=subject, message=html_message, recipients=recipients, connection=connection)
    except Exception as e:
        errorMessage = str(e)
    return errorMessage


def sendRefusDossier(recipients, establishment_id, student_name, notes):
    """
    Envoie un email au parent pour l'informer que son dossier d'inscription
    nécessite des corrections.
    
    Args:
        recipients: Email du destinataire (parent)
        establishment_id: ID de l'établissement
        student_name: Nom complet de l'élève
        notes: Motifs du refus (contenu du champ notes du RegistrationForm)
    
    Returns:
        str: Message d'erreur si échec, chaîne vide sinon
    """
    errorMessage = ''
    try:
        EMAIL_REFUS_SUBJECT = '[N3WT-SCHOOL] Dossier d\'inscription - Corrections requises'
        context = {
            'BASE_URL': settings.BASE_URL,
            'URL_DJANGO': settings.URL_DJANGO,
            'student_name': student_name,
            'notes': notes
        }
        connection = getConnection(establishment_id)
        subject = EMAIL_REFUS_SUBJECT
        html_message = render_to_string('emails/refus_dossier.html', context)
        sendMail(subject=subject, message=html_message, recipients=recipients, connection=connection)
        logger.info(f"Email de refus envoyé à {recipients} pour l'élève {student_name}")
    except Exception as e:
        errorMessage = str(e)
        logger.error(f"Erreur lors de l'envoi de l'email de refus: {errorMessage}")
    return errorMessage


def sendValidationDossier(recipients, establishment_id, student_name, class_name=None):
    """
    Envoie un email au parent pour l'informer que le dossier d'inscription
    a été validé.
    
    Args:
        recipients: Email du destinataire (parent)
        establishment_id: ID de l'établissement
        student_name: Nom complet de l'élève
        class_name: Nom de la classe attribuée (optionnel)
    
    Returns:
        str: Message d'erreur si échec, chaîne vide sinon
    """
    errorMessage = ''
    try:
        EMAIL_VALIDATION_SUBJECT = '[N3WT-SCHOOL] Dossier d\'inscription validé'
        context = {
            'BASE_URL': settings.BASE_URL,
            'URL_DJANGO': settings.URL_DJANGO,
            'student_name': student_name,
            'class_name': class_name
        }
        connection = getConnection(establishment_id)
        subject = EMAIL_VALIDATION_SUBJECT
        html_message = render_to_string('emails/validation_dossier.html', context)
        sendMail(subject=subject, message=html_message, recipients=recipients, connection=connection)
        logger.info(f"Email de validation envoyé à {recipients} pour l'élève {student_name}")
    except Exception as e:
        errorMessage = str(e)
        logger.error(f"Erreur lors de l'envoi de l'email de validation: {errorMessage}")
    return errorMessage


def sendRefusDefinitif(recipients, establishment_id, student_name, notes):
    """
    Envoie un email au parent pour l'informer que le dossier d'inscription
    a été définitivement refusé.
    
    Args:
        recipients: Email du destinataire (parent)
        establishment_id: ID de l'établissement
        student_name: Nom complet de l'élève
        notes: Motifs du refus
    
    Returns:
        str: Message d'erreur si échec, chaîne vide sinon
    """
    errorMessage = ''
    try:
        EMAIL_REFUS_DEFINITIF_SUBJECT = '[N3WT-SCHOOL] Dossier d\'inscription refusé'
        context = {
            'BASE_URL': settings.BASE_URL,
            'URL_DJANGO': settings.URL_DJANGO,
            'student_name': student_name,
            'notes': notes
        }
        connection = getConnection(establishment_id)
        subject = EMAIL_REFUS_DEFINITIF_SUBJECT
        html_message = render_to_string('emails/refus_definitif.html', context)
        sendMail(subject=subject, message=html_message, recipients=recipients, connection=connection)
        logger.info(f"Email de refus définitif envoyé à {recipients} pour l'élève {student_name}")
    except Exception as e:
        errorMessage = str(e)
        logger.error(f"Erreur lors de l'envoi de l'email de refus définitif: {errorMessage}")
    return errorMessage