from rest_framework import serializers
from .models import *
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from bson import ObjectId

class NivelSerializer(serializers.ModelSerializer):
    permissions = serializers.SerializerMethodField()
    
    class Meta:
        model = Nivel
        fields = "__all__"
    
    def get_permissions(self, obj):
        return [
            {
                'app_label': perm['app_label'],
                'codename': perm['codename'],
                'name': Permission.objects.get(codename=perm['codename'], content_type__app_label=perm['app_label']).name
            }
            for perm in obj.permissions
        ]
        

class NivelOnlyWriteSerializer(serializers.ModelSerializer):
    permissions = serializers.JSONField()
    
    class Meta:
        model = Nivel
        fields = "__all__"
    
    


class UsuarioSerializer(serializers.ModelSerializer):
    
    nivel = NivelSerializer(many=True, read_only=True)
    
    class Meta:
        model = Usuario
        fields = '__all__'
        extra_kwargs = {
            'is_superuser': {'read_only': True},
            'email': {'required': True},
            'password': {'required': True},
        }

class UsuarioOnlyWriteSerializer(serializers.ModelSerializer):
    
    nivel = serializers.CharField()
    foto = serializers.CharField(required=False)
    is_active = serializers.BooleanField(required=False)
    is_staff = serializers.BooleanField(required=False)
    
    class Meta:
        model = Usuario
        fields = '__all__'
        extra_kwargs = {
            'is_superuser': {'read_only': True},
            'email': {'required': True},
            'password': {'required': True},
            'nivel': {'required': False},
        }
    
    def validate(self, attrs):
        #print(f"Validate Attrs: {attrs}")
        if 'nivel' in attrs:
            if not Nivel.objects.get(id=ObjectId(attrs['nivel'])):
                raise serializers.ValidationError("Nivel not found.")
        return super().validate(attrs)


    def create(self, validated_data):
        
        if 'is_active' not in validated_data or validated_data['is_active'] is None:
            validated_data['is_active'] = True
        if 'is_staff' not in validated_data or validated_data['is_staff'] is None:
            validated_data['is_staff'] = True

        if 'nivel' in validated_data:
            validated_data['nivel_id'] = [ObjectId(validated_data.pop('nivel'))]

        obj_id = self.Meta.model.objects.mongo_insert(validated_data)
        obj_data = self.Meta.model.objects.mongo_find_one({'_id': ObjectId(obj_id)})

        obj_data['id'] = obj_data.pop('_id')
        if 'nivel_id' in obj_data:
            obj_data['nivel'] = obj_data.pop('nivel_id')
        
        obj = self.Meta.model(**obj_data)
        
        return obj

    def update(self, instance, validated_data):
        ### Nivel ###
        if 'nivel' in validated_data:
            validated_data['nivel_id'] = [ObjectId(validated_data.pop('nivel', []))]
            

        obj = self.Meta.model.objects.mongo_update_one({'_id': instance.id}, {'$set':validated_data})
        
        if obj:
            return instance
        else:
            return None
        


class UsuarioSimpleSerializer(serializers.ModelSerializer):
    
    class Meta:
        model = Usuario
        fields = ['id', 'first_name', 'last_name', 'email', 'telefone', 'foto', 'is_active', 'categoria']
        


class ContentTypesSerializer(serializers.ModelSerializer):
    class Meta:
        model = ContentType
        fields = ['app_label']

class PermissionSerializer(serializers.ModelSerializer):
    content_type = ContentTypesSerializer()

    class Meta:
        model = Permission
        fields = ['content_type', 'codename', 'name']

    def to_representation(self, instance):
        data = super().to_representation(instance)
        return {
            'app_label': data['content_type']['app_label'],
            'codename': data['codename'],
            'name': data['name']
        }
        

# from rest_framework_simplejwt.views import TokenRefreshView
# from rest_framework_simplejwt.tokens import RefreshToken
# from rest_framework_simplejwt.exceptions import TokenError
# from rest_framework_simplejwt.serializers import TokenRefreshSerializer

# class CustomTokenRefreshSerializer(TokenRefreshSerializer):
#     def validate(self, attrs):
#         try:
#             data = super().validate(attrs)
#         except TokenError as e:
#             raise e
#         refresh = RefreshToken(attrs['refresh'])
#         data['access_token'] = str(refresh.access_token)
#         ## filter access from data
#         data.pop('access')
#         return data