from rest_framework import serializers
from django.contrib.auth import get_user_model
from django.contrib.auth.password_validation import validate_password
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

User = get_user_model()

# --- 1. Serializer pour le Login (Celui qui manquait) ---
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    @classmethod
    def get_token(cls, user):
        token = super().get_token(user)
        token['role'] = user.role
        token['email'] = user.email
        return token

    def validate(self, attrs):
        email = attrs.get('email') or attrs.get('username')
        if email:
            try:
                u = User.objects.get(email=email)
                if not u.is_active:
                    raise serializers.ValidationError(
                        "Votre compte n'est pas encore activé. L'équipe GOON valide votre inscription ; vous recevrez un email lorsqu'il sera actif."
                    )
            except User.DoesNotExist:
                pass
        data = super().validate(attrs)
        # Infos retournées dans la réponse HTTP du login
        data.update({
            'user_id': self.user.id,
            'email': self.user.email,
            'role': self.user.role,
            'first_name': self.user.first_name,
            'last_name': self.user.last_name,
            'is_verified': self.user.is_verified
        })
        return data

class UserSerializer(serializers.ModelSerializer):
    """Serializer pour afficher les infos de l'utilisateur (Profil)."""
    class Meta:
        model = User
        fields = ['id', 'email', 'first_name', 'last_name', 'phone', 'role', 'is_verified', 'is_active', 'date_joined']
        read_only_fields = ['id', 'email', 'role', 'is_verified', 'date_joined']


class AdminUserDetailSerializer(serializers.ModelSerializer):
    """Serializer admin : édition complète (comme Django admin) — is_verified, is_active, is_staff, is_superuser, role, mentor."""
    class Meta:
        model = User
        fields = [
            'id', 'email', 'first_name', 'last_name', 'phone',
            'role', 'mentor', 'is_verified', 'is_active', 'is_staff', 'is_superuser',
            'date_joined',
        ]
        read_only_fields = ['id', 'email', 'date_joined']


class AdminUserListSerializer(UserSerializer):
    """Liste admin avec global_progress pour le dashboard."""
    global_progress = serializers.SerializerMethodField()

    class Meta(UserSerializer.Meta):
        fields = UserSerializer.Meta.fields + ['global_progress']

    def get_global_progress(self, obj):
        from formations.models import Formation
        from formations.models import UserProgress
        all_formations = Formation.objects.all()
        if not all_formations:
            return 0
        total = 0
        for f in all_formations:
            total_lessons = f.lessons.count()
            if total_lessons == 0:
                continue
            completed = UserProgress.objects.filter(user=obj, lesson__formation=f, is_completed=True).count()
            total += (completed / total_lessons) * 100
        return round(total / len(all_formations), 2)

class InviteUserSerializer(serializers.ModelSerializer):
    """Serializer pour l'invitation d'un utilisateur par l'Admin."""
    class Meta:
        model = User
        fields = ['email', 'first_name', 'last_name', 'phone']

    def create(self, validated_data):
        """
        Crée un utilisateur invité sans mot de passe (il sera défini à l'activation).
        Le modèle User utilise l'email comme identifiant (pas de username).
        """
        user = User.objects.create_user(
            email=validated_data['email'],
            password=None,
            first_name=validated_data['first_name'],
            last_name=validated_data['last_name'],
            phone=validated_data.get('phone', ''),
            is_active=True,   # Actif mais non encore vérifié
            is_verified=False
        )
        user.set_unusable_password()  # Empêche la connexion avant activation
        user.save(update_fields=['password', 'first_name', 'last_name', 'phone', 'is_active', 'is_verified'])
        # Auto-assignation mentor (Option C) pour les étudiants invités
        from .utils import get_mentor_to_assign
        mentor = get_mentor_to_assign()
        if mentor and user.role == User.Role.USER:
            user.mentor = mentor
            user.save(update_fields=['mentor'])
        return user


class InviteMentorSerializer(serializers.ModelSerializer):
    """Invitation d'un mentor par l'Admin (même flow OTP que l'invitation utilisateur, rôle MENTOR)."""
    class Meta:
        model = User
        fields = ['email', 'first_name', 'last_name', 'phone']

    def create(self, validated_data):
        user = User.objects.create_user(
            email=validated_data['email'],
            password=None,
            first_name=validated_data['first_name'],
            last_name=validated_data['last_name'],
            phone=validated_data.get('phone', ''),
            is_active=True,
            is_verified=False,
            role=User.Role.MENTOR,
        )
        user.set_unusable_password()
        user.save(update_fields=['password', 'first_name', 'last_name', 'phone', 'is_active', 'is_verified', 'role'])
        return user


class RegisterSerializer(serializers.ModelSerializer):
    """Inscription publique : mêmes champs que l'invitation + mot de passe. Compte créé inactif (admin active)."""
    password = serializers.CharField(write_only=True, validators=[validate_password])
    password_confirm = serializers.CharField(write_only=True)

    class Meta:
        model = User
        fields = ['email', 'first_name', 'last_name', 'phone', 'password', 'password_confirm']

    def validate_email(self, value):
        if User.objects.filter(email__iexact=value).exists():
            raise serializers.ValidationError("Un compte existe déjà avec cet email.")
        return value

    def validate(self, data):
        if data['password'] != data['password_confirm']:
            raise serializers.ValidationError({"password_confirm": "Les mots de passe ne correspondent pas."})
        return data

    def create(self, validated_data):
        validated_data.pop('password_confirm')
        password = validated_data.pop('password')
        user = User.objects.create_user(
            **validated_data,
            password=password,
            is_active=False,
            is_verified=False,
        )
        # Auto-assignation mentor (Option C) à l'inscription
        from .utils import get_mentor_to_assign
        mentor = get_mentor_to_assign()
        if mentor and user.role == User.Role.USER:
            user.mentor = mentor
            user.save(update_fields=['mentor'])
        return user


class ActivateAccountSerializer(serializers.Serializer):
    """Serializer pour l'activation du compte avec OTP et nouveau mot de passe."""
    email = serializers.EmailField()
    otp_code = serializers.CharField(max_length=6)
    password = serializers.CharField(write_only=True, validators=[validate_password])
    password_confirm = serializers.CharField(write_only=True)

    def validate(self, data):
        if data['password'] != data['password_confirm']:
            raise serializers.ValidationError({"password": "Les mots de passe ne correspondent pas."})
        return data


class ForgotPasswordSerializer(serializers.Serializer):
    email = serializers.EmailField()


class ResetPasswordSerializer(serializers.Serializer):
    email = serializers.EmailField()
    otp_code = serializers.CharField(max_length=6)
    password = serializers.CharField(write_only=True, validators=[validate_password])
    password_confirm = serializers.CharField(write_only=True)

    def validate(self, data):
        if data['password'] != data['password_confirm']:
            raise serializers.ValidationError({"password_confirm": "Les mots de passe ne correspondent pas."})
        return data