from rest_framework import serializers
from Auth.models import Profile, ProfileRole
from Establishment.models import Establishment
from Subscriptions.models import Guardian, RegistrationForm
from School.models import Teacher
from N3wtSchool import settings
from django.utils import timezone
import pytz

class ProfileSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=False)
    password = serializers.CharField(write_only=True)
    roles = serializers.SerializerMethodField()

    class Meta:
        model = Profile
        fields = ['id', 'password', 'email', 'code', 'datePeremption', 'username', 'roles', 'roleIndexLoginDefault', 'first_name', 'last_name']
        extra_kwargs = {'password': {'write_only': True}}

    def get_roles(self, obj):
        roles = ProfileRole.objects.filter(profile=obj)
        roles_data = []
        for role in roles:
            # Récupérer l'ID de l'associated_person en fonction du type de rôle
            if role.role_type == ProfileRole.RoleType.PROFIL_PARENT:
                guardian = Guardian.objects.filter(profile_role=role).first()
                id_associated_person = guardian.id if guardian else None
            else:
                teacher = Teacher.objects.filter(profile_role=role).first()
                id_associated_person = teacher.id if teacher else None

            roles_data.append({
                'id_associated_person': id_associated_person,
                'role_type': role.role_type,
                'establishment': role.establishment.id,
                'establishment_name': role.establishment.name,
                'is_active': role.is_active,
            })
        return roles_data

    def create(self, validated_data):
        user = Profile(
            username=validated_data['username'],
            email=validated_data['email'],
            code=validated_data.get('code', ''),
            datePeremption=validated_data.get('datePeremption', '')
        )
        user.set_password(validated_data['password'])
        user.full_clean()
        user.save()
        return user

    def update(self, instance, validated_data):
        password = validated_data.pop('password', None)
        instance = super().update(instance, validated_data)

        if password:
            instance.set_password(password)

        instance.full_clean()
        instance.save()
        return instance

    def to_representation(self, instance):
        ret = super().to_representation(instance)
        ret['password'] = '********'
        ret['roles'] = self.get_roles(instance)
        return ret

class ProfileRoleSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=False)
    profile = serializers.PrimaryKeyRelatedField(queryset=Profile.objects.all(), required=False)
    profile_data = ProfileSerializer(write_only=True, required=False)
    associated_profile_email = serializers.SerializerMethodField()
    associated_person = serializers.SerializerMethodField()
    updated_date_formatted = serializers.SerializerMethodField()

    class Meta:
        model = ProfileRole
        fields = ['id', 'role_type', 'establishment', 'is_active', 'profile', 'profile_data', 'associated_profile_email', 'associated_person', 'updated_date_formatted']

    def create(self, validated_data):
        profile_data = validated_data.pop('profile_data', None)
        profile = validated_data.pop('profile', None)

        if profile_data:
            profile_serializer = ProfileSerializer(data=profile_data)
            profile_serializer.is_valid(raise_exception=True)
            profile = profile_serializer.save()
        elif profile:
            profile = Profile.objects.get(id=profile.id)

        profile_role = ProfileRole.objects.create(profile=profile, **validated_data)
        return profile_role

    def update(self, instance, validated_data):
        profile_data = validated_data.pop('profile_data', None)
        profile = validated_data.pop('profile', None)

        if profile_data:
            profile_serializer = ProfileSerializer(instance.profile, data=profile_data)
            profile_serializer.is_valid(raise_exception=True)
            profile = profile_serializer.save()
        elif profile:
            profile = Profile.objects.get(id=profile.id)

        if profile:
            instance.profile = profile

        instance.role_type = validated_data.get('role_type', instance.role_type)
        instance.establishment_id = validated_data.get('establishment', instance.establishment.id)
        instance.is_active = validated_data.get('is_active', instance.is_active)
        instance.save()
        return instance

    def get_associated_profile_email(self, obj):
        if obj.profile:
            return obj.profile.email
        return None

    def get_associated_person(self, obj):
        if obj.role_type == ProfileRole.RoleType.PROFIL_PARENT:
            guardian = Guardian.objects.filter(profile_role=obj).first()
            if guardian:
                students = guardian.student_set.all()
                students_list = []
                for student in students:
                    registration_form = RegistrationForm.objects.filter(student=student).first()
                    registration_status = registration_form.status if registration_form else None
                    students_list.append({
                        "id": f"{student.id}",
                        "student_name": f"{student.last_name} {student.first_name}",
                        "registration_status": registration_status
                    })
                return {
                    "id": guardian.id,
                    "guardian_name": f"{guardian.last_name} {guardian.first_name}",
                    "students": students_list
                }
        else:
            teacher = Teacher.objects.filter(profile_role=obj).first()
            if teacher:
                classes = teacher.schoolclass_set.all()
                classes_list = [{"id": classe.id, "name": classe.atmosphere_name} for classe in classes]
                specialities = teacher.specialities.all()
                specialities_list = [{"name": speciality.name, "color_code": speciality.color_code} for speciality in specialities]
                return {
                    "id": teacher.id,
                    "teacher_name": f"{teacher.last_name} {teacher.first_name}",
                    "classes": classes_list,
                    "specialities": specialities_list
                }
        return None

    def get_updated_date_formatted(self, obj):
        utc_time = timezone.localtime(obj.updated_date)
        local_tz = pytz.timezone(settings.TZ_APPLI)
        local_time = utc_time.astimezone(local_tz)

        return local_time.strftime("%d-%m-%Y %H:%M")