from rest_framework import serializers
from django.contrib.auth.models import User
from .models import PerfilUsuario
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework.exceptions import PermissionDenied

class PerfilUsuarioSerializer(serializers.ModelSerializer):
    class Meta:
        model = PerfilUsuario
        fields = ['rol', 'aprobado']

class UsuarioSerializer(serializers.ModelSerializer):
    rol = serializers.CharField(source='perfil.rol', read_only=True)
    aprobado = serializers.BooleanField(source='perfil.aprobado', read_only=True)

    class Meta:
        model = User
        fields = ['id', 'username', 'email', 'first_name', 'last_name', 'rol', 'aprobado', 'is_active']

class RegistroSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    rol = serializers.ChoiceField(choices=PerfilUsuario.ROLES)
    
    class Meta:
        model = User
        fields = ['username', 'email', 'first_name', 'last_name', 'password', 'rol']
        
    def create(self, validated_data):
        rol = validated_data.pop('rol')
        user = User.objects.create_user(**validated_data)
        
        # El signal de models crea el perfil, ahora actualizamos el rol solicitado
        user.perfil.rol = rol
        user.perfil.save()
        
        return user

class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        data = super().validate(attrs)
        
        user = self.user
        perfil = getattr(user, 'perfil', None)
        
        if perfil and not perfil.aprobado:
            raise PermissionDenied("Tu cuenta está en espera de aprobación por parte del Administrador.")
            
        data['rol'] = perfil.rol if perfil else 'AUXILIAR'
        data['username'] = user.username
        data['first_name'] = user.first_name
        data['last_name'] = user.last_name
        data['email'] = user.email
        data['aprobado'] = perfil.aprobado if perfil else False
        
        return data
