from rest_framework import serializers
from course.models import Course
from flashcard.serializers import FlashcardListSerializer, PublicFlashcardSerializer
from exercise.serializers import ExerciseListSerializer, PublicExerciseSerializer
from knowledge.serializers import KnowledgeListSerializer, PublicKnowledgeSerializer

class CourseSerializer(serializers.ModelSerializer):
    flashcards = serializers.SerializerMethodField()
    exercises = serializers.SerializerMethodField()
    knowledges = serializers.SerializerMethodField()
    # Le champ contient la méthode SerializerMethodField, qui appelle elle-même la methode get_nomDuChamp
    # à chaque fois que le champ sera appelé, sa valeur sera définie par la méthode en question
    # on pourrait également définir ce champ dans la view, mais il faudrait alors créer un serializer puis le modifier à l'intérieur de la view pour avoir à la fois cette info et les autres ci-dessous
    emailsAllowedToAccess = serializers.ListField(
        child=serializers.EmailField(),
        required=False,
        default=list
    )
    content = serializers.ListField(
        child=serializers.CharField(),
        required=False,
        default=list
    )
    tags = serializers.JSONField(required=False, default=dict)
    class Meta:
        model = Course
        fields = ['name', 'academicLevel', 'subjectStudied', 'content', 'flashcards', 'exercises', 'knowledges', 'user', 'publicIdentifier', 'tags', 'shared', 'emailsAllowedToAccess', 'accessCode']

    def get_knowledges(self, instance):
        queryset = instance.knowledges
        serializer = KnowledgeListSerializer(queryset, many=True)
        return serializer.data

    def get_flashcards(self, instance):  # instance est l'instance de Course
        queryset = instance.flashcards  # flashcards instance.flashcards contient un objet RelatedManager, qui gère les relations entre une instance et des éléments d'une autre base de donnée, et dont la methode __str__ renvoie par défaut la liste des id des objets.
        serializer = FlashcardListSerializer(queryset, many=True)
        return serializer.data
    
    def get_exercises(self, instance):
        queryset = instance.exercises
        serializer = ExerciseListSerializer(queryset, many=True)
        return serializer.data


class CourseListSerializer(serializers.ModelSerializer):
    flashcards = serializers.SerializerMethodField()
    exercises = serializers.SerializerMethodField()
    emailsAllowedToAccess = serializers.ListField(
        child=serializers.EmailField()
    )
    class Meta:
        model = Course
        fields = ['name', 'publicIdentifier', 'knowledges', 'flashcards', 'exercises', 'academicLevel', 'subjectStudied', 'shared', 'emailsAllowedToAccess', 'accessCode']

    def get_flashcards(self, instance):  # instance est l'instance de Course
        queryset = instance.flashcards  # flashcards instance.flashcards contient un objet RelatedManager, qui gère les relations entre une instance et des éléments d'une autre base de donnée, et dont la methode __str__ renvoie par défaut la liste des id des objets.
        serializer = FlashcardListSerializer(queryset, many=True)
        return serializer.data
    
    def get_exercises(self, instance):
        queryset = instance.exercises
        serializer = ExerciseListSerializer(queryset, many=True)
        return serializer.data
    

class CreateCourseSerializer(serializers.ModelSerializer):

    emailsAllowedToAccess = serializers.ListField(
        child=serializers.EmailField(),
        required=False,
        default=list
    )
    content = serializers.ListField(
        child=serializers.CharField(),
        required=False,
        default=list
    )
    tags = serializers.JSONField(required=False, default=dict)
    class Meta:
        model = Course
        fields = ['name', 'academicLevel', 'subjectStudied', 'content', 'copied_from', 'tags', 'user', 'publicIdentifier', 'shared', 'emailsAllowedToAccess', 'accessCode']



class PublicCourseSerializer(serializers.ModelSerializer):
    """
    Cette classe renvoie l'ensemble des données d'une flashcard lors d'un partage. Elle ne fait pas directement le lien avec le cours.
    C'est en effet préférable de faire ce lien en front car dans certains cas, l'utilisateur peut ne pas avoir de compte (pour les cours publiques).
    Ce serializer est en lecture seule pour empêcher toute modification.
    """
    flashcards = serializers.SerializerMethodField()
    exercises = serializers.SerializerMethodField()
    knowledges = serializers.SerializerMethodField()

    name = serializers.CharField(read_only=True)
    academicLevel = serializers.CharField(read_only=True)
    subjectStudied = serializers.CharField(read_only=True)
    training = serializers.CharField(read_only=True)
    tags = serializers.JSONField(read_only=True)
    footnotes = serializers.JSONField(read_only=True)
    content = serializers.JSONField(read_only=True)

    class Meta:
        model = Course
        fields = ['name', 'academicLevel', 'subjectStudied', 'training', 'tags', 'footnotes', 'content', 'knowledges', 'flashcards', 'exercises']
        read_only_fields = fields

    def get_knowledges(self, instance):
        queryset = instance.knowledges
        serializer = PublicKnowledgeSerializer(queryset, many=True)
        return serializer.data
    
    def get_flashcards(self, instance):
        queryset = instance.flashcards
        serializer = PublicFlashcardSerializer(queryset, many=True)
        return serializer.data
    
    def get_exercises(self, instance):
        queryset = instance.exercises
        serializer = PublicExerciseSerializer(queryset, many=True)
        return serializer.data



# Il y a un problème dans la récupération des cours
# ça vient probablement des données qui sont renvoyées lors de la création du cours (mais à checker)
# Je viens de "brancher" les tokens, continuer de checker que tout va bien et qu'il y a pas de problème dans le front
