module.exports = {
    friendlyName: "Find",
    description: "Find Eleves Classe.",

    inputs: {
        search: { type: "string" },
        idEvaluation: { type: "string", required: true },
        anneeScolaire: { type: "string", required: true },
        codeClasse: { type: "string", required: true },
        matricule: { type: "string", required: true }
    },

    exits: {
        notFound: { statusCode: 404 },
        error: { statusCode: 500 }
    },

    fn: async function (inputs, exits) {
        try {
            const { id, user } = this.req.token;
            console.log("inputs", inputs);
            // VERIFICATION DU CODE ECOLE
            if (!user.codeEcole) {
                return exits.notFound({ message: "Code Ecole manquant" });
            }

            const ecoleVerif = await Ecoles.find({ codeEcole: user.codeEcole }).then(_.first);
            if (!ecoleVerif) {
                return exits.notFound({ message: "Ecole non trouvée" });
            }

            // VERIF ANNEE SCOLAIRE
            if (!inputs.anneeScolaire) {
                return exits.notFound({ message: "Année scolaire manquante" });
            }

            // Gestion pagination
            this.req.query.limit = this.req.query.limit || "10";
            this.req.query.skip = this.req.query.skip || "0";

            let userCodeEcole = user.codeEcole;

            if (user.typeUser === 'ELEVE') {
                const eleve = await Eleves.find({ nom: user.nom }).then(_.first);
                if (!eleve) {
                    return exits.notFound({ message: "Eleve non trouvé" });
                }
                inputs.matricule = eleve.matricule;
                user.codeUser = eleve.matricule;

                const classeEleve = await AttributionClasse.findOne({
                    codeEcole: user.codeEcole,
                    matricule: user.codeUser,
                    trimSem: 1,
                    anneeScolaire: inputs.anneeScolaire
                });

                if (!classeEleve) {
                    return exits.notFound({ message: "Classe non trouvée" });
                }
                inputs.codeClasse = classeEleve.codeClasse;
            }

            // Vérification cycle classe
            const cycleClasse = await ClasseUniteScolaire.findOne({
                codeEcole: userCodeEcole,
                codeClasse: inputs.codeClasse,
            });
            if (!cycleClasse) {
                return exits.notFound({ message: "Cycle non défini" });
            }

            // Récupération des matières
            const matieres = await PrimMatiereClasse.find({
                codeEcole: userCodeEcole,
                codeClasse: inputs.codeClasse,
                anneeScolaire: inputs.anneeScolaire
            }).sort('nordre ASC');

            const matieresWithDetails = await Promise.all(matieres.map(async matiere => {
                const matiereClasse = await PrimMatiere.findOne({ CodPrimMatiere: matiere.CodPrimMatiere });
                if (matiereClasse) {
                    matiere.libelleMatiere = matiereClasse.libelleMatiere;
                }

                const note = await PrimNote.findOne({
                    codeEcole: userCodeEcole,
                    anneeScolaire: inputs.anneeScolaire,
                    idSall: inputs.codeClasse,
                    CodPrimMatiere: matiere.CodPrimMatiere,
                    idEvaluation: inputs.idEvaluation,
                });

                if (note) {
                    const detNote = await PrimNoteDet.findOne({
                        codeEcole: userCodeEcole,
                        matricule: inputs.matricule,
                        anneeScolaire: inputs.anneeScolaire,
                        CodNote: note.CodNote
                    });
                    matiere.note = note;
                    matiere.detNote = detNote;
                }

                matiere.matricule = inputs.matricule;
                return matiere;
            }));

            const [moyenneEleve, seuilSalle, indiceCalcul, statsMoyennes, estNote] = await Promise.all([
                PrimMoyenne.findOne({
                    codeEcole: userCodeEcole,
                    codEleve: inputs.matricule,
                    idEvaluation: inputs.idEvaluation,
                    idSall: inputs.codeClasse,
                    anneeScolaire: inputs.anneeScolaire,
                }),
                PrimSeuil.findOne({
                    codeEcole: userCodeEcole,
                    codeClasse: inputs.codeClasse,
                }),

                (async () => {
                    const [indice, count] = await Promise.all([
                        PrimIndiceCalcul.findOne({
                            codeEcole: userCodeEcole,
                            codeClasse: inputs.codeClasse,
                        }),
                        AttributionClasse.count({
                            codeEcole: userCodeEcole,
                            codeClasse: inputs.codeClasse,
                            anneeScolaire: inputs.anneeScolaire,
                            trimSem: 1
                        })
                    ]);

                    // Si indice existe, on ajoute le count comme propriété
                    if (indice) {
                        indice.nombreEleves = count;
                    } else {
                        // Si indice n'existe pas, on crée un objet avec le count
                        return { nombreEleves: count };
                    }
                    return indice;
                })(),
                (async () => {
                    const moyennesClasse = await PrimMoyenne.find({
                        codeEcole: userCodeEcole,
                        idEvaluation: inputs.idEvaluation,
                        idSall: inputs.codeClasse,
                        anneeScolaire: inputs.anneeScolaire
                    });

                    if (moyennesClasse.length > 0) {
                        // Conversion correcte des strings français (13,22) en nombres
                        const moyennes = moyennesClasse
                            .map(m => {
                                // Remplace la virgule par un point et convertit en nombre
                                const num = parseFloat(m.moyenneEval.replace(',', '.'));
                                return isNaN(num) ? null : num;
                            })
                            .filter(m => m !== null); // Exclure les conversions échouées

                        if (moyennes.length > 0) {
                            return {
                                plusForteMoyenne: Math.max(...moyennes),
                                plusFaibleMoyenne: Math.min(...moyennes),
                                moyenneClasse: moyennes.reduce((a, b) => a + b, 0) / moyennes.length,
                                count: moyennes.length
                            };
                        }
                    }
                    return {
                        plusForteMoyenne: null,
                        plusFaibleMoyenne: null,
                        moyenneClasse: null,
                        count: 0
                    };
                })(),
                (async () => {
                    const note = await PrimNote.find({
                        codeEcole: userCodeEcole,
                        anneeScolaire: inputs.anneeScolaire,
                        idSall: inputs.codeClasse,
                        idEvaluation: inputs.idEvaluation,
                    }).then(_.first);

                    if (note) {
                        return true;
                    } else {
                        return false
                    };
                })(),
            ]);

            // Conversion pour la moyenne de l'élève
            if (moyenneEleve && moyenneEleve.moyenneEval) {
                moyenneEleve.moyenneEvalNum = parseFloat(moyenneEleve.moyenneEval.replace(',', '.'));
            }

            return exits.success({
                matieres: matieresWithDetails,
                moyenne: {
                    ...moyenneEleve,
                    moyenneEvalNum: moyenneEleve ? parseFloat(moyenneEleve.moyenneEval).toFixed(2) || null : null,
                    statsClasse: statsMoyennes
                },
                seuilSalle,
                indiceCalcul,
                estNote
            });

        } catch (err) {
            sails.log.error(err);
            return exits.error({ message: "Erreur serveur" });
        }
    }
};