# Fichier: services/email_service.py
"""
Service centralisé pour l'envoi des emails.
Tous les emails de l'application passent par ce module.
"""

from flask import current_app, render_template, url_for
from flask_mail import Message
from extensions import mail
from datetime import datetime


# ========================================================================
# CONFIGURATION
# ========================================================================

DEFAULT_SENDER_NAME = "MCyber Diagnostic"


# ========================================================================
# FONCTION D'ENVOI GÉNÉRIQUE
# ========================================================================

def send_email(to, subject, template, **kwargs):
    """
    Envoie un email en utilisant un template HTML.
    
    Args:
        to (str ou list): Destinataire(s)
        subject (str): Sujet de l'email
        template (str): Nom du template (sans extension, ex: 'welcome')
        **kwargs: Variables à passer au template
    
    Returns:
        bool: True si envoyé, False sinon
    """
    try:
        # Ajouter l'année courante pour le footer
        kwargs['current_year'] = datetime.now().year
        
        # Construire le message
        msg = Message(
            subject=subject,
            recipients=[to] if isinstance(to, str) else to
        )
        
        # Rendre le template HTML
        msg.html = render_template(f'emails/{template}.html', **kwargs)
        
        # Version texte de secours (fallback)
        if _template_exists(f'emails/{template}.txt'):
            msg.body = render_template(f'emails/{template}.txt', **kwargs)
        else:
            msg.body = _html_to_text(msg.html)
        
        # Envoyer
        mail.send(msg)
        
        current_app.logger.info(f"📧 Email envoyé à {to}: {subject}")
        return True
        
    except Exception as e:
        current_app.logger.error(f"❌ Erreur envoi email à {to}: {e}", exc_info=True)
        return False


def _template_exists(template_name):
    """Vérifie si un template existe."""
    try:
        current_app.jinja_env.get_template(template_name)
        return True
    except:
        return False


def _html_to_text(html):
    """Conversion basique HTML vers texte."""
    import re
    text = re.sub(r'<br\s*/?>', '\n', html)
    text = re.sub(r'</p>', '\n\n', text)
    text = re.sub(r'<[^>]+>', '', text)
    text = re.sub(r'\n{3,}', '\n\n', text)
    return text.strip()


# ========================================================================
# EMAILS DE BIENVENUE / ACTIVATION
# ========================================================================

def send_welcome_email(user, reset_url):
    """
    Email de bienvenue avec lien d'activation du mot de passe.
    Destinataire: Nouvel utilisateur créé par Admin/Manager/Distributeur
    Template: welcome.html
    """
    return send_email(
        to=user.email,
        subject="Bienvenue sur MCyber Diagnostic - Activez votre compte",
        template="welcome",
        user=user,
        reset_url=reset_url,
        company_name=user.company_name or "Votre entreprise"
    )


def send_account_validated_email(user, reset_url):
    """
    Email de validation de compte (après approbation admin).
    Destinataire: Compte créé par un Distributeur et validé par l'Admin
    Template: account_validated.html
    """
    return send_email(
        to=user.email,
        subject="✅ Votre compte MCyber Diagnostic a été validé",
        template="account_validated",
        user=user,
        reset_url=reset_url,
        company_name=user.company_name or "Votre entreprise"
    )


def send_pending_account_email(user, distributor_name):
    """
    Email informant que le compte est en attente de validation.
    Destinataire: Compte créé par un Distributeur (avant validation admin)
    Template: pending_account.html
    """
    return send_email(
        to=user.email,
        subject="⏳ Votre compte MCyber Diagnostic - En attente de validation",
        template="pending_account",
        user=user,
        distributor_name=distributor_name,
        company_name=user.company_name or "Votre entreprise"
    )


def send_team_invitation_email(user, reset_url, inviter_name):
    """
    Email d'invitation à rejoindre une équipe (Manager ou Distributeur).
    Destinataire: Nouveau membre d'équipe
    Template: team_invitation.html
    """
    return send_email(
        to=user.email,
        subject="👥 Invitation à rejoindre l'équipe - MCyber Diagnostic",
        template="team_invitation",
        user=user,
        reset_url=reset_url,
        inviter_name=inviter_name
    )


def send_password_reset_email(user, reset_url):
    """
    Email de réinitialisation de mot de passe.
    Destinataire: Utilisateur ayant demandé un reset
    Template: password_reset.html
    """
    return send_email(
        to=user.email,
        subject="🔐 Réinitialisation de votre mot de passe - MCyber Diagnostic",
        template="password_reset",
        user=user,
        reset_url=reset_url
    )


# ========================================================================
# NOTIFICATIONS ADMIN (Template: admin_notification.html)
# ========================================================================

def send_admin_new_account_notification(admin_email, new_user, created_by):
    """
    Notification à l'admin qu'un compte a été créé.
    Destinataire: Admin
    """
    return send_email(
        to=admin_email,
        subject=f"📋 Nouveau compte créé: {new_user.company_name or new_user.email}",
        template="admin_notification",
        notification_type="new_account",
        new_user=new_user,
        created_by=created_by
    )


def send_admin_new_diagnostic_notification(admin_email, rapport, user):
    """
    Notification à l'admin qu'un diagnostic a été réalisé.
    Destinataire: Admin
    """
    return send_email(
        to=admin_email,
        subject=f"📊 Nouveau diagnostic: {rapport.nom_client} ({rapport.score_total}%)",
        template="admin_notification",
        notification_type="new_diagnostic",
        rapport=rapport,
        user=user
    )


def send_admin_pending_validation_notification(admin_email, new_user, distributor):
    """
    Notification à l'admin qu'un compte attend validation.
    Destinataire: Admin
    """
    return send_email(
        to=admin_email,
        subject=f"⏳ Compte en attente de validation: {new_user.company_name or new_user.email}",
        template="admin_notification",
        notification_type="pending_validation",
        new_user=new_user,
        distributor=distributor
    )


def send_quota_alert_to_admin(admin_email, user, percentage, used, limit):
    """
    Alerte quota envoyée à l'admin pour un utilisateur.
    Destinataire: Admin
    """
    return send_email(
        to=admin_email,
        subject=f"⚠️ Quota {percentage}% pour {user.company_name or user.email}",
        template="admin_notification",
        notification_type="quota_alert",
        user=user,
        percentage=percentage,
        used=used,
        limit=limit
    )


def send_engagement_alert_to_admin(admin_email, user, days_left):
    """
    Alerte fin d'engagement envoyée à l'admin.
    Destinataire: Admin
    """
    return send_email(
        to=admin_email,
        subject=f"📅 Engagement J-{days_left}: {user.company_name or user.email}",
        template="admin_notification",
        notification_type="engagement_alert",
        user=user,
        days_left=days_left
    )


def send_distributor_action_to_admin(admin_email, distributor, action, target_user):
    """
    Notification à l'admin qu'un distributeur a effectué une action.
    Destinataire: Admin
    
    Args:
        action: 'suspended', 'reactivated', 'audit_blocked', 'audit_unblocked', 'deleted'
    """
    action_labels = {
        'suspended': ('a suspendu', '🔒'),
        'reactivated': ('a réactivé', '✅'),
        'audit_blocked': ('a bloqué les diagnostics de', '⛔'),
        'audit_unblocked': ('a réactivé les diagnostics de', '✅'),
        'deleted': ('a supprimé', '🗑️')
    }
    
    label, emoji = action_labels.get(action, ('a modifié', '📝'))
    
    return send_email(
        to=admin_email,
        subject=f"{emoji} Action Distributeur : {distributor.company_name or distributor.email} {label} {target_user.company_name or target_user.email}",
        template="admin_notification",
        notification_type="distributor_action",
        distributor=distributor,
        action=action,
        action_label=label,
        action_emoji=emoji,
        target_user=target_user
    )


# ========================================================================
# NOTIFICATIONS DISTRIBUTEUR (Template: distributor_notification.html)
# ========================================================================

def send_distributor_account_validated_notification(distributor_email, validated_user):
    """
    Notification au distributeur qu'un de ses comptes a été validé.
    Destinataire: Distributeur
    """
    return send_email(
        to=distributor_email,
        subject=f"✅ Compte validé: {validated_user.company_name or validated_user.email}",
        template="distributor_notification",
        notification_type="account_validated",
        validated_user=validated_user
    )


def send_quota_alert_to_distributor(distributor_email, user, percentage, used, limit):
    """
    Alerte quota envoyée au distributeur pour un de ses clients.
    Destinataire: Distributeur
    """
    return send_email(
        to=distributor_email,
        subject=f"⚠️ Quota {percentage}% pour {user.company_name or user.email}",
        template="distributor_notification",
        notification_type="quota_alert",
        user=user,
        percentage=percentage,
        used=used,
        limit=limit
    )


def send_engagement_alert_to_distributor(distributor_email, user, days_left):
    """
    Alerte fin d'engagement envoyée au distributeur.
    Destinataire: Distributeur
    """
    return send_email(
        to=distributor_email,
        subject=f"📅 Engagement J-{days_left}: {user.company_name or user.email}",
        template="distributor_notification",
        notification_type="engagement_alert",
        user=user,
        days_left=days_left
    )


def send_action_confirmation_to_distributor(distributor_email, action, target_user):
    """
    Confirmation au distributeur de l'action qu'il vient d'effectuer.
    Destinataire: Distributeur
    
    Args:
        action: 'suspended', 'reactivated', 'audit_blocked', 'audit_unblocked'
    """
    action_labels = {
        'suspended': ('suspendu', '🔒'),
        'reactivated': ('réactivé', '✅'),
        'audit_blocked': ('bloqué les diagnostics pour', '⛔'),
        'audit_unblocked': ('réactivé les diagnostics pour', '✅')
    }
    
    label, emoji = action_labels.get(action, ('modifié', '📝'))
    
    return send_email(
        to=distributor_email,
        subject=f"{emoji} Confirmation : Compte {target_user.company_name or target_user.email} {label}",
        template="distributor_notification",
        notification_type="action_confirmation",
        action=action,
        action_label=label,
        action_emoji=emoji,
        target_user=target_user
    )


def send_admin_action_to_distributor(distributor_email, action, target_user):
    """
    Notification au distributeur que l'admin a agi sur un de ses clients.
    Destinataire: Distributeur
    
    Args:
        action: 'suspended', 'reactivated', 'audit_blocked', 'audit_unblocked', 'deleted'
    """
    action_labels = {
        'suspended': ('suspendu', '🔒'),
        'reactivated': ('réactivé', '✅'),
        'audit_blocked': ('bloqué les diagnostics de', '⛔'),
        'audit_unblocked': ('réactivé les diagnostics de', '✅'),
        'deleted': ('supprimé', '🗑️')
    }
    
    label, emoji = action_labels.get(action, ('modifié', '📝'))
    
    return send_email(
        to=distributor_email,
        subject=f"{emoji} Action Admin sur votre client : {target_user.company_name or target_user.email} {label}",
        template="distributor_notification",
        notification_type="admin_action",
        action=action,
        action_label=label,
        action_emoji=emoji,
        target_user=target_user
    )


# ========================================================================
# NOTIFICATIONS MANAGER (Template: manager_notification.html)
# ========================================================================

def send_manager_new_user_confirmation(manager_email, new_user):
    """
    Confirmation au manager qu'il a créé un utilisateur.
    Destinataire: Manager
    """
    return send_email(
        to=manager_email,
        subject=f"✅ Utilisateur créé: {new_user.company_name or new_user.email}",
        template="manager_notification",
        notification_type="new_user",
        new_user=new_user
    )


def send_manager_diagnostic_notification(manager_email, rapport, user):
    """
    Notification au manager qu'un de ses utilisateurs a fait un diagnostic.
    Destinataire: Manager
    """
    return send_email(
        to=manager_email,
        subject=f"📊 Nouveau diagnostic de {user.company_name or user.email}",
        template="manager_notification",
        notification_type="diagnostic",
        rapport=rapport,
        user=user
    )


# ========================================================================
# ALERTES QUOTA UTILISATEUR (Template: quota_alert.html)
# ========================================================================

def send_quota_warning_email(user, percentage, used, limit):
    """
    Alerte quota à 80%.
    Destinataire: User ou Manager concerné
    """
    return send_email(
        to=user.email,
        subject=f"⚠️ Quota à {percentage}% - MCyber Diagnostic",
        template="quota_alert",
        user=user,
        percentage=percentage,
        used=used,
        limit=limit
    )


def send_quota_critical_email(user, used, limit):
    """
    Alerte quota atteint (100%).
    Destinataire: User ou Manager concerné
    """
    return send_email(
        to=user.email,
        subject="🚨 Quota mensuel atteint - MCyber Diagnostic",
        template="quota_alert",
        user=user,
        percentage=100,
        used=used,
        limit=limit
    )


# ========================================================================
# ALERTES ENGAGEMENT (Template: engagement_reminder.html)
# ========================================================================

def send_engagement_reminder_email(user, days_left):
    """
    Rappel fin d'engagement (J-30 ou J-7).
    Destinataire: User ou Manager concerné
    """
    urgency = "🔴" if days_left <= 7 else "🟠"
    return send_email(
        to=user.email,
        subject=f"{urgency} Fin d'engagement dans {days_left} jours - MCyber Diagnostic",
        template="engagement_reminder",
        user=user,
        days_left=days_left
    )


# ========================================================================
# SUSPENSION / RÉACTIVATION / BLOCAGE (Template: account_status.html)
# ========================================================================

def send_account_suspended_email(user, suspended_by_name, suspended_by_role):
    """
    Email informant l'utilisateur que son compte a été suspendu.
    Destinataire: Compte suspendu (Manager/User/Distributeur)
    """
    return send_email(
        to=user.email,
        subject="🔒 Votre compte MCyber Diagnostic a été suspendu",
        template="account_status",
        action="suspended",
        user=user,
        suspended_by_name=suspended_by_name,
        suspended_by_role=suspended_by_role
    )


def send_account_reactivated_email(user, reactivated_by_name, reactivated_by_role):
    """
    Email informant l'utilisateur que son compte a été réactivé.
    Destinataire: Compte réactivé (Manager/User/Distributeur)
    """
    return send_email(
        to=user.email,
        subject="✅ Votre compte MCyber Diagnostic a été réactivé",
        template="account_status",
        action="reactivated",
        user=user,
        reactivated_by_name=reactivated_by_name,
        reactivated_by_role=reactivated_by_role
    )


def send_audit_blocked_email(user, blocked_by_name, blocked_by_role):
    """
    Email informant l'utilisateur que la création d'audits a été bloquée.
    Destinataire: Compte concerné (Manager/User)
    """
    return send_email(
        to=user.email,
        subject="⛔ Création de diagnostics bloquée sur votre compte",
        template="account_status",
        action="audit_blocked",
        user=user,
        blocked_by_name=blocked_by_name,
        blocked_by_role=blocked_by_role
    )


def send_audit_unblocked_email(user, unblocked_by_name, unblocked_by_role):
    """
    Email informant l'utilisateur que la création d'audits a été réactivée.
    Destinataire: Compte concerné (Manager/User)
    """
    return send_email(
        to=user.email,
        subject="✅ Création de diagnostics réactivée sur votre compte",
        template="account_status",
        action="audit_unblocked",
        user=user,
        unblocked_by_name=unblocked_by_name,
        unblocked_by_role=unblocked_by_role
    )