"""Ce fichier contient des fonctions qui permettent de convertir des données complexes,
 telles que des querysets et des instances de modèle, en types de données Python qui peuvent ensuite
 être facilement rendus en JSON, XML ou d'autres types de contenu.
"""

from rest_framework import serializers
from .models import Competence, PcpFeGroupe, PreferencesListe, Poste, Notation, Administre, CustomUser, Grade, MarquesGroupe, \
    Garnison, \
    SousVivier, Domaine, Filiere, FMOB, Fonction, FormationEmploi, Marque, Decision

from . import constants


class FileSVSerializer(serializers.Serializer):
    """Cette classe ne sera utilisée que pour valider si le fichier SV est un vrai fichier.
    """
    SV = serializers.FileField()

    class Meta:
        fields = ['sv_file']


class ScoringValidator(serializers.Serializer):
    """ pour interprêter et valider le contenu JSON """
    sous_vivier_id = serializers.CharField(max_length=100, required=True, allow_null=False, allow_blank=False)

class FileCompetenceSerializer(serializers.Serializer):
    """Cette classe ne sera utilisée que pour valider si les fichiers competence_v1 et competence_v2 sont un vrais fichier.
    """
    competence_v1 = serializers.FileField()
    competence_v2 = serializers.FileField()

    class Meta:
        fields = ['competence_file_v1', 'competence_file_v2']


class FileSerializer(serializers.Serializer):
    """Cette classe ne sera utilisée que pour valider si les fichiers Donnees_BO_ADT, REO, ZPROPAF, FMOB, domaine_filiere, insee_mapin et diplomes sont des vrais fichiers.
    """
    Donnees_BO_ADT = serializers.FileField(help_text="Fichier BO ADT 1.1")
    REO = serializers.FileField()
    ZPROPAF = serializers.FileField()
    FMOB = serializers.FileField()
    domaine_filiere = serializers.FileField()
    insee_maping = serializers.FileField()
    diplomes = serializers.FileField()

    class Meta:
        fields = ['Donnees_BO_ADT', 'REO', 'ZPROPAF', 'FMOB', 'domaine_filiere', 'insee_maping', 'diplomes']

class AlimentationReferentielSerializer(serializers.Serializer):
    """ Valide que les données sont bien des fichiers. """

    referentiel_fe = serializers.FileField(help_text="Référentiel FE")

    class Meta:
        fields = ['referentiel_fe']


class NotationSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets Notation en type json contenant uniquement les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = Notation
        fields = '__all__'


class GestionnaireSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets customusers en type json contenant uniquement les informations mentionnées dans la variable fields.

    """
    class Meta:
        model = CustomUser
        fields = ['grade', 'first_name', 'last_name', 'email']


class PreferencesListeSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets preferencesliste en type json contenant uniquement les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = PreferencesListe
        fields = '__all__'


class FmobSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets Fmob en type json contenant uniquement les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = FMOB
        fields = '__all__'


class SimpleDecisionSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets decision en type json contenant uniquement les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = Decision
        fields = '__all__'


class AdministreDecisionSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets decisions en type json contenant les informations mentionnées dans la variable fields.
    Et à l'ajout des variables poste_fe_code, poste_fe_libelle, poste_fe_garnison liés à la decision au json.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    poste_fe_code = serializers.CharField(source='poste.formation_emploi.fe_code', read_only=True)
    poste_fe_libelle = serializers.CharField(source='poste.formation_emploi.fe_libelle', read_only=True)
    poste_fe_garnison = serializers.CharField(source='poste.formation_emploi.garnison.gar_lieu', read_only=True)

    class Meta:
        model = Decision
        fields = '__all__'


class MarquesGroupeSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets marquegroupes en type json contenant uniquement les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = MarquesGroupe
        fields = '__all__'


class MarqueSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets marque en type json contenant les informations de marque et les champs de marquesgroupe liés à chaque marque.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    groupe_marques = MarquesGroupeSerializer()

    class Meta:
        model = Marque
        fields = '__all__'


class DomaineSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets domaines en type json contenant les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = Domaine
        fields = '__all__'


class FiliereSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets filières en type json contenant les informations de filière
    et les champs du domaine liés à chaque filiere.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    domaine = DomaineSerializer()

    class Meta:
        model = Filiere
        fields = '__all__'


class GradeSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets grades en type json contenant les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = Grade
        fields = '__all__'


class GarnisonSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets garnisons en type json contenant les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = Garnison
        fields = '__all__'


class FormationEmploiSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets FormationEmploi en type json contenant les informations de FormationEmploi
    et le champs garnison lieu liés à chaque FormationEmploi.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """

    class MereSerializer(serializers.ModelSerializer):
        """Classe de représentation de la FE mère"""
        fe_code = serializers.ReadOnlyField()
        fe_libelle = serializers.ReadOnlyField()

        class Meta:
            model = FormationEmploi
            fields = ['fe_code', 'fe_libelle']


    garnison = serializers.CharField(source=f'{FormationEmploi.Cols.REL_GARNISON}.gar_lieu')
    mere = MereSerializer(read_only=True)

    class Meta:
        model = FormationEmploi
        fields = '__all__'


class FonctionSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets fonctions en type json contenant les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = Fonction
        fields = '__all__'


class SousVivierSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets SousVivier en type json contenant les informations du SousVivier
    et la/le gestionnaire responsable de chaque SousVivier.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    gestionnaire = GestionnaireSerializer()

    class Meta:
        model = SousVivier
        fields = '__all__'


class SousVivierAssociationSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la creation d'un json contenant les champs du SousVivier
    et les champs de filière liés à chaque SousVivier.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    filiere = FiliereSerializer()
    sous_vivier = SousVivierSerializer()

    class Meta:
        fields = '__all__'

class CompetenceSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets competences en type json contenant les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = Competence
        fields = '__all__'

class PosteSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets postes en type json contenant les champs du poste
    et les champs de fonction, formation_emploi, sous_vivier et decisions liés à chaque poste. Cette classe va également ordonner le json par p_id et valider certaines variables.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    fonction = FonctionSerializer()
    formation_emploi = FormationEmploiSerializer()
    sous_vivier = SousVivierSerializer(allow_null=True)
    sous_vivier_id = serializers.IntegerField(write_only=True, allow_null=True)
    decisions = SimpleDecisionSerializer(many=True)
    p_nb_prepositionne = serializers.IntegerField(read_only=True)
    p_nb_positionne = serializers.IntegerField(read_only=True)
    p_nb_omi_en_cours = serializers.IntegerField(read_only=True)
    p_nb_omi_active = serializers.IntegerField(read_only=True)


    class Meta:
        model = Poste
        ordering = ['p_id']
        fields = '__all__'




class AdministreSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets administres en type json contenant les champs de l'administré
    et les champs de fonction, formation_emploi, sous_vivier, decisions, grade et Fmob  liés à chaque administré. Cette classe va également ordonner le json par a_id_sap.
    Les variables qui seront affichées dans le json sont celles mentionnées dans la variable fields.
    """
    a_id_sap = serializers.ReadOnlyField()
    formation_emploi = FormationEmploiSerializer(read_only=True)
    sous_vivier = SousVivierSerializer(read_only=True)
    sous_vivier_id = serializers.IntegerField(write_only=True, allow_null=True)
    fonction = FonctionSerializer(read_only=True)
    grade = GradeSerializer(read_only=True)
    decision = AdministreDecisionSerializer(read_only=True)
    fmobs = FmobSerializer(many=True)

    class Meta:
        model = Administre
        ordering = ['a_id_sap']
        fields = '__all__'

        """
        fields = ["a_id_sap",
                  "formation_emploi",
                  "formation_emploi_id",
                  "fonction",
                  "fonction_id",
                  "sous_vivier",
                  "sous_vivier_id",
                  "grade",
                  "decision",
                  "fmobs",
                  "a_liste_id_marques",
                  "a_liste_id_competences",
                  "a_nom",
                  "a_prenom",
                  "a_sexe",
                  "a_fonction",
                  "a_code_fonction",
                  "a_domaine",
                  "a_filiere",
                  "a_nf",
                  "a_categorie",
                  "a_domaine_futur",
                  "a_filiere_futur",
                  "a_nf_futur",
                  "a_bureau_gestion",
                  "a_date_entree_service",
                  "a_arme",
                  "a_rg_origine_recrutement",
                  "a_date_naissance",
                  "a_liste_depts_souhaites",
                  "a_interruption_service",
                  "a_situation_fam",
                  "a_date_rdc",
                  "a_date_dernier_acr",
                  "a_sap_conjoint",
                  "a_statut_pam",
                  "a_notes_gestionnaire",
                  "a_notes_partagees"]
        read_only_fields = ("a_id_sap",)
         """


class DecisionSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets decisions en type json contenant les champs de decision
    et les champs de notation, poste et administre liés à chaque decision . Cette classe va également ordonner le json par de_date_decision.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    notation = NotationSerializer()
    poste = PosteSerializer()
    administre = AdministreSerializer()

    class Meta:
        model = Decision
        fields = '__all__'
        ordering = ['de_date_decision']



class PcpFeGroupeSerializer(serializers.ModelSerializer):
    """Cette classe sera responsable de la conversion des objets PcpFeGroupe en type json contenant les informations mentionnées dans la variable fields.
    Si fields='__all__', alors toutes les variables liées à cette classe seront affichées dans le json.
    """
    class Meta:
        model = PcpFeGroupe
        fields = '__all__'
