const express = require('express');
const sql = require('mssql');
const cors = require('cors');

const app = express();
app.use(cors());
app.use(express.json());

const sqlConfig = {
    user: 'RG-Competences',
    password: 'P@ssw0rd2026!',
    server: '192.168.0.3',
    database: 'RG-Competences',
    options: {
        encrypt: true,
        trustServerCertificate: true,
        enableArithAbort: true
    }
};

// ═══════════════════════════════════════════════════════
// UTILITAIRE : LOG HISTORIQUE (NOUVELLE VERSION - UNE LIGNE PAR ACTION)
// ═══════════════════════════════════════════════════════
async function logHistoryComplete(data) {
    try {
        const pool = await sql.connect(sqlConfig);
        await pool.request()
            .input('record_id', sql.NVarChar, data.record_id)
            .input('action_type', sql.NVarChar, data.action_type)
            .input('action_description', sql.NVarChar, data.action_description)
            .input('author_email', sql.NVarChar, data.author_email)
            .input('author_name', sql.NVarChar, data.author_name)
            .input('author_role', sql.NVarChar, data.author_role)
            .input('campus', sql.NVarChar, data.campus || null)
            .input('ip_address', sql.NVarChar, data.ip_address || null)
            // Nouvelles colonnes
            .input('auto_evaluation_old', sql.NVarChar, data.auto_evaluation_old || null)
            .input('auto_evaluation_new', sql.NVarChar, data.auto_evaluation_new || null)
            .input('evaluation_tuteur_old', sql.NVarChar, data.evaluation_tuteur_old || null)
            .input('evaluation_tuteur_new', sql.NVarChar, data.evaluation_tuteur_new || null)
            .input('date_action_old', sql.Date, data.date_action_old || null)
            .input('date_action_new', sql.Date, data.date_action_new || null)
            .input('date_action_rre_old', sql.Date, data.date_action_rre_old || null)
            .input('date_action_rre_new', sql.Date, data.date_action_rre_new || null)
            .input('date_eval_tuteur_old', sql.Date, data.date_eval_tuteur_old || null)
            .input('date_eval_tuteur_new', sql.Date, data.date_eval_tuteur_new || null)
            .input('commentaire_formateur_old', sql.NVarChar, data.commentaire_formateur_old || null)
            .input('commentaire_formateur_new', sql.NVarChar, data.commentaire_formateur_new || null)
            .input('commentaire_rre_old', sql.NVarChar, data.commentaire_rre_old || null)
            .input('commentaire_rre_new', sql.NVarChar, data.commentaire_rre_new || null)
            .input('commentaire_old', sql.NVarChar, data.commentaire_old || null)
            .input('commentaire_new', sql.NVarChar, data.commentaire_new || null)
            .query(`
                INSERT INTO [dbo].[tbl_Historique_Evaluations] 
                (record_id, action_type, action_description, 
                 author_email, author_name, author_role, campus, ip_address,
                 auto_evaluation_old, auto_evaluation_new,
                 evaluation_tuteur_old, evaluation_tuteur_new,
                 date_action_old, date_action_new,
                 date_action_rre_old, date_action_rre_new,
                 date_eval_tuteur_old, date_eval_tuteur_new,
                 commentaire_formateur_old, commentaire_formateur_new,
                 commentaire_rre_old, commentaire_rre_new,
                 commentaire_old, commentaire_new)
                VALUES 
                (@record_id, @action_type, @action_description,
                 @author_email, @author_name, @author_role, @campus, @ip_address,
                 @auto_evaluation_old, @auto_evaluation_new,
                 @evaluation_tuteur_old, @evaluation_tuteur_new,
                 @date_action_old, @date_action_new,
                 @date_action_rre_old, @date_action_rre_new,
                 @date_eval_tuteur_old, @date_eval_tuteur_new,
                 @commentaire_formateur_old, @commentaire_formateur_new,
                 @commentaire_rre_old, @commentaire_rre_new,
                 @commentaire_old, @commentaire_new)
            `);
        console.log('✅ Historique complet enregistré:', data.action_type);
    } catch (error) {
        console.error('❌ Erreur log historique:', error);
    }
}

// ═══════════════════════════════════════════════════════
// AUTHENTIFICATION
// ═══════════════════════════════════════════════════════
async function getUserWithPermissions(userPrincipalName) {
    try {
        const pool = await sql.connect(sqlConfig);

        const superUserResult = await pool.request()
            .input('userPrincipalName', sql.NVarChar, userPrincipalName)
            .query(`
                SELECT TOP 1 
                    userPrincipalName,
                    nom + ' ' + prenom as nom_complet,
                    nom,
                    prenom,
                    campus,
                    COALESCE(role, 'super') as role
                FROM [dbo].[tbl_SuperUtilisateur]
                WHERE userPrincipalName = @userPrincipalName
                AND actif = 1
            `);

        if (superUserResult.recordset.length > 0) {
            const superUser = superUserResult.recordset[0];
            const userRole = superUser.role || 'super';

            // Définir les permissions selon le rôle
            let permissions = {};

            if (userRole === 'lecteur') {
                // Lecteur : peut voir son campus mais rien modifier
                permissions = {
                    peut_valider_evaluations: false,
                    peut_gerer_formateurs: false,
                    peut_saisir_evaluations: false,
                    peut_voir_tous_campus: false,  // ✅ Limité à son campus
                    peut_exporter_donnees: true,   // Peut exporter
                    peut_usurper_identite: false,
                    peut_modifier: false  // ✅ Ne peut pas modifier
                };
            } else {
                // Super : peut modifier son campus uniquement
                permissions = {
                    peut_valider_evaluations: true,
                    peut_gerer_formateurs: true,
                    peut_saisir_evaluations: true,
                    peut_voir_tous_campus: false,  // ✅ Limité à son campus
                    peut_exporter_donnees: true,
                    peut_usurper_identite: true,
                    peut_modifier: true  // ✅ Peut modifier
                };
            }

            return {
                id: superUser.userPrincipalName,
                email: superUser.userPrincipalName,
                name: superUser.prenom || superUser.nom,
                nomComplet: superUser.nom_complet,
                campus: superUser.campus,
                role: userRole,
                permissions: permissions
            };
        }

        const userResult = await pool.request()
            .input('userPrincipalName', sql.NVarChar, userPrincipalName)
            .query(`
                SELECT TOP 1 
                    userPrincipalName,
                    nom_dip as nom_complet,
                    Nom_brut as nom,
                    givenname as prenom,
                    Campus,
                    'formateur' as role
                FROM [dbo].[v_R_Promo_Formateur_Referent]
                WHERE userPrincipalName = @userPrincipalName
                
                UNION ALL
                
                SELECT TOP 1 
                    userPrincipalName,
                    nom + ' ' + prenom as nom_complet,
                    nom,
                    prenom,
                    campus as Campus,
                    'rre' as role
                FROM [dbo].[tbl_Responsable_RRE]
                WHERE userPrincipalName = @userPrincipalName
                AND actif = 1
            `);

        if (userResult.recordset.length === 0) return null;

        const user = userResult.recordset[0];
        const role = user.role || 'rre';

        return {
            id: user.userPrincipalName,
            email: user.userPrincipalName,
            name: user.prenom || user.nom,
            nomComplet: user.nom_complet,
            campus: user.Campus,
            role: role,
            permissions: {
                peut_valider_evaluations: role === 'rre',
                peut_gerer_formateurs: role === 'rre',
                peut_saisir_evaluations: true,
                peut_voir_tous_campus: role === 'rre',
                peut_exporter_donnees: role === 'rre',
                peut_modifier: true
            }
        };
    } catch (error) {
        console.error('❌ getUserWithPermissions:', error);
        throw error;
    }
}

// ═══════════════════════════════════════════════════════
// SUPER-UTILISATEUR : LISTE DES FORMATEURS ET RRE
// ═══════════════════════════════════════════════════════
app.get('/api/super/users', async (req, res) => {
    try {
        const userRole = req.headers['x-user-role'];

        if (userRole !== 'super') {
            return res.status(403).json({ error: 'Accès réservé aux super-utilisateurs' });
        }

        const pool = await sql.connect(sqlConfig);

        const formateurs = await pool.request().query(`
            SELECT DISTINCT
                userPrincipalName as id,
                nom_dip as nom_complet,
                Nom_brut as nom,
                givenname as prenom,
                Campus as campus,
                'formateur' as role
            FROM [dbo].[v_R_Promo_Formateur_Referent]
            WHERE userPrincipalName IS NOT NULL
            ORDER BY nom_dip ASC
        `);

        const rres = await pool.request().query(`
            SELECT 
                userPrincipalName as id,
                nom + ' ' + prenom as nom_complet,
                nom,
                prenom,
                campus,
                'rre' as role
            FROM [dbo].[tbl_Responsable_RRE]
            WHERE actif = 1
            ORDER BY nom ASC, prenom ASC
        `);

        const allUsers = [
            ...formateurs.recordset.map(f => ({
                id: f.id,
                name: f.nom_complet,
                email: f.id,
                campus: f.campus,
                role: 'formateur'
            })),
            ...rres.recordset.map(r => ({
                id: r.id,
                name: r.nom_complet,
                email: r.id,
                campus: r.campus,
                role: 'rre'
            }))
        ];

        res.json(allUsers);
        console.log('✅ Liste des utilisateurs pour super-user:', allUsers.length);
    } catch (error) {
        console.error('❌ Erreur /api/super/users:', error);
        res.status(500).json({ error: 'Erreur serveur' });
    }
});

// ═══════════════════════════════════════════════════════
// SUPER-UTILISATEUR : USURPER UNE IDENTITÉ
// ═══════════════════════════════════════════════════════
app.post('/api/super/impersonate', async (req, res) => {
    try {
        const userRole = req.headers['x-user-role'];
        const { targetEmail } = req.body;

        if (userRole !== 'super') {
            return res.status(403).json({ error: 'Accès réservé aux super-utilisateurs' });
        }

        if (!targetEmail) {
            return res.status(400).json({ error: 'Email cible requis' });
        }

        const targetUser = await getUserWithPermissions(targetEmail);

        if (!targetUser || targetUser.role === 'super' || targetUser.role === 'lecteur') {
            return res.status(404).json({ error: 'Utilisateur cible non trouvé ou invalide' });
        }

        console.log(`🎭 Super-user usurpe l'identité de: ${targetUser.email} (${targetUser.role})`);

        res.json({
            success: true,
            impersonatedUser: targetUser
        });
    } catch (error) {
        console.error('❌ Erreur impersonate:', error);
        res.status(500).json({ error: 'Erreur serveur' });
    }
});

app.post('/auth/verify', async (req, res) => {
    const { email } = req.body;
    console.log('🔍 Vérification:', email);
    try {
        const user = await getUserWithPermissions(email);
        if (user) {
            console.log('✅ User:', user.role, user.campus);
            res.json({ valid: true, user });
        } else {
            console.log('❌ Non trouvé');
            res.status(403).json({ valid: false });
        }
    } catch (error) {
        console.error('❌ Erreur auth:', error);
        res.status(500).json({ error: 'Erreur serveur' });
    }
});

// ═══════════════════════════════════════════════════════
// UTILITAIRE : OBTENIR L'UTILISATEUR EFFECTIF
// ═══════════════════════════════════════════════════════
function getEffectiveUser(headers) {
    const realRole = headers['x-user-role'];
    const impersonatedEmail = headers['x-impersonated-email'];
    const impersonatedRole = headers['x-impersonated-role'];
    const impersonatedCampus = headers['x-impersonated-campus'];

    if (realRole === 'super' && impersonatedEmail) {
        return {
            email: impersonatedEmail,
            role: impersonatedRole,
            campus: impersonatedCampus,
            isImpersonating: true,
            isSuperUser: true
        };
    }

    return {
        email: headers['x-user-email'],
        role: headers['x-user-role'],
        campus: headers['x-user-campus'],
        isImpersonating: false,
        isSuperUser: realRole === 'super',
        isLecteur: realRole === 'lecteur'
    };
}

// ═══════════════════════════════════════════════════════
// FILTRES - CAMPUS
// ═══════════════════════════════════════════════════════
app.get('/api/campus-list', async (req, res) => {
    try {
        const effectiveUser = getEffectiveUser(req.headers);
        const { email, role, campus, isSuperUser, isLecteur } = effectiveUser;

        const pool = await sql.connect(sqlConfig);
        let result;

        // 🔥 SUPER OU LECTEUR SANS USURPATION : SON campus uniquement
        if ((isSuperUser || isLecteur) && !effectiveUser.isImpersonating) {
            if (campus) {
                result = await pool.request()
                    .input('userCampus', sql.NVarChar, campus)
                    .query(`
                        SELECT DISTINCT Campus 
                        FROM [dbo].[v_R_Promo_Formateur_Etudiant]
                        WHERE Campus = @userCampus
                        ORDER BY Campus ASC
                    `);
            } else {
                // Si pas de campus défini, tous les campus (fallback)
                result = await pool.request().query(`
                    SELECT DISTINCT Campus 
                    FROM [dbo].[v_R_Promo_Formateur_Etudiant]
                    WHERE Campus IS NOT NULL AND Campus != ''
                    ORDER BY Campus ASC
                `);
            }
        }
        // Formateur : ses campus uniquement
        else if (role === 'formateur' && email) {
            result = await pool.request()
                .input('userEmail', sql.NVarChar, email)
                .query(`
                    SELECT DISTINCT Campus 
                    FROM [dbo].[v_R_Promo_Formateur_Etudiant]
                    WHERE Campus IS NOT NULL AND Campus != ''
                    AND userPrincipalName = @userEmail
                    ORDER BY Campus ASC
                `);
        }
        // RRE : son campus uniquement
        else if (role === 'rre' && campus) {
            result = await pool.request()
                .input('userCampus', sql.NVarChar, campus)
                .query(`
                    SELECT DISTINCT Campus 
                    FROM [dbo].[v_R_Promo_Formateur_Etudiant]
                    WHERE Campus = @userCampus
                    ORDER BY Campus ASC
                `);
        }
        // Fallback : tous les campus
        else {
            result = await pool.request().query(`
                SELECT DISTINCT Campus 
                FROM [dbo].[v_R_Promo_Formateur_Etudiant]
                WHERE Campus IS NOT NULL AND Campus != ''
                ORDER BY Campus ASC
            `);
        }

        res.json(result.recordset.map(r => r.Campus));
        console.log(`📍 Campus (${role}${isSuperUser ? ' [SUPER]' : ''}${isLecteur ? ' [LECTEUR]' : ''}${effectiveUser.isImpersonating ? ' [USURPÉ]' : ''}):`, result.recordset.length);
    } catch (error) {
        console.error('❌ campus-list:', error);
        res.status(500).json({ error: 'Erreur campus' });
    }
});

// ═══════════════════════════════════════════════════════
// FILTRES - PROMOTIONS
// ═══════════════════════════════════════════════════════
app.get('/api/promo-list', async (req, res) => {
    try {
        const { campus } = req.query;
        const effectiveUser = getEffectiveUser(req.headers);
        const { email, role, campus: userCampus, isSuperUser, isLecteur } = effectiveUser;

        const pool = await sql.connect(sqlConfig);
        const request = pool.request();

        let query = `
            SELECT DISTINCT NOM_DIP as promo
            FROM [dbo].[v_R_Promo_Formateur_Etudiant]
            WHERE NOM_DIP IS NOT NULL AND NOM_DIP != ''
        `;

        // 🔥 SUPER OU LECTEUR SANS USURPATION : filtrer par SON campus
        if ((isSuperUser || isLecteur) && !effectiveUser.isImpersonating) {
            if (userCampus) {
                query += ` AND Campus = @userCampus`;
                request.input('userCampus', sql.NVarChar, userCampus);
            }
        }
        // Formateur : filtrer par son email
        else if (role === 'formateur' && email) {
            query += ` AND userPrincipalName = @userEmail`;
            request.input('userEmail', sql.NVarChar, email);
        }
        // RRE : filtrer par son campus
        else if (role === 'rre' && userCampus) {
            query += ` AND Campus = @userCampus`;
            request.input('userCampus', sql.NVarChar, userCampus);
        }

        // Filtre par campus sélectionné
        if (campus && campus !== 'tous') {
            query += ` AND Campus = @campus`;
            request.input('campus', sql.NVarChar, campus);
        }

        query += ` ORDER BY NOM_DIP ASC`;

        const result = await request.query(query);
        res.json(result.recordset.map(r => r.promo));
        console.log(`🎓 Promotions (${role}${isSuperUser ? ' [SUPER]' : ''}${isLecteur ? ' [LECTEUR]' : ''}):`, result.recordset.length);
    } catch (error) {
        console.error('❌ promo-list:', error);
        res.status(500).json({ error: 'Erreur promotions' });
    }
});

// ═══════════════════════════════════════════════════════
// FILTRES - ÉTUDIANTS
// ═══════════════════════════════════════════════════════
app.get("/api/student-list", async (req, res) => {
    try {
        const { campus, promo } = req.query;

        const effectiveUser = getEffectiveUser(req.headers);
        const { email, role, campus: userCampus, isSuperUser, isLecteur } = effectiveUser;

        const pool = await sql.connect(sqlConfig);
        const request = pool.request();

        let query = `
            SELECT 
                LOGin as id,
                PRENOM + ' ' + NOM as name,
                Campus,
                NOM_DIP as formation
            FROM [dbo].[v_R_Promo_Formateur_Etudiant]
            WHERE LOGin IS NOT NULL
                AND LOGin <> ''
        `;

        const conditions = [];

        // 🔥 SUPER OU LECTEUR SANS USURPATION : filtrer par SON campus
        if ((isSuperUser || isLecteur) && !effectiveUser.isImpersonating) {
            if (userCampus) {
                conditions.push("Campus = @userCampus");
                request.input("userCampus", sql.NVarChar, userCampus);
            }
        }
        // Formateur : uniquement SES étudiants
        else if (role === "formateur" && email) {
            conditions.push("userPrincipalName = @userEmail");
            request.input("userEmail", sql.NVarChar, email);
        }
        // RRE : uniquement étudiants de SON campus
        else if (role === "rre" && userCampus) {
            conditions.push("Campus = @userCampus");
            request.input("userCampus", sql.NVarChar, userCampus);
        }

        // Filtre par campus sélectionné
        if (campus && campus !== "tous") {
            conditions.push("Campus = @campus");
            request.input("campus", sql.NVarChar, campus);
        }

        // Filtre par promo sélectionnée
        if (promo && promo !== "tous") {
            conditions.push("NOM_DIP = @promo");
            request.input("promo", sql.NVarChar, promo);
        }

        if (conditions.length > 0) {
            query += " AND " + conditions.join(" AND ");
        }

        query += " ORDER BY NOM ASC, PRENOM ASC";

        const result = await request.query(query);

        res.json(result.recordset);
        console.log(
            `👥 Étudiants (${role}${isSuperUser ? ' [SUPER]' : ''}${isLecteur ? ' [LECTEUR]' : ''}${effectiveUser.isImpersonating ? ' [USURPÉ]' : ''}):`,
            result.recordset.length
        );
    } catch (error) {
        console.error("❌ student-list, error:", error);
        res.status(500).json({ error: "Erreur étudiants" });
    }
});

// ═══════════════════════════════════════════════════════
// DONNÉES PROMO
// ═══════════════════════════════════════════════════════
app.get('/api/promo-data', async (req, res) => {
    try {
        const userRole = req.headers['x-user-role'];
        const userCampus = req.headers['x-user-campus'];
        const userEmail = req.headers['x-user-email'];

        const pool = await sql.connect(sqlConfig);
        const request = pool.request();

        let query = `
            SELECT 
                LOGin,
                NOM,
                PRENOM,
                Campus,
                NOM_DIP,
                Annee,
                userPrincipalName as formateurEmail
            FROM [dbo].[v_R_Promo_Formateur_Etudiant]
            WHERE LOGin IS NOT NULL
        `;

        if (userRole === 'formateur' && userEmail) {
            query += ` AND userPrincipalName = @userEmail`;
            request.input('userEmail', sql.NVarChar, userEmail);
        } else if ((userRole === 'rre' || userRole === 'super' || userRole === 'lecteur') && userCampus) {
            query += ` AND Campus = @userCampus`;
            request.input('userCampus', sql.NVarChar, userCampus);
        }

        query += ` ORDER BY Campus ASC, NOM_DIP ASC, NOM ASC, PRENOM ASC`;

        const result = await request.query(query);
        res.json(result.recordset);
        console.log(`✅ promo-data (${userRole}):`, result.recordset.length);
    } catch (error) {
        console.error('❌ promo-data:', error);
        res.status(500).json({ error: 'Erreur promo-data' });
    }
});

// ═══════════════════════════════════════════════════════
// RÉCUPÉRER HISTORIQUE (NOUVELLE VERSION)
// ═══════════════════════════════════════════════════════
app.get('/api/history/:studentId', async (req, res) => {
    try {
        const { studentId } = req.params;
        const pool = await sql.connect(sqlConfig);

        const result = await pool.request()
            .input('studentId', sql.NVarChar, studentId)
            .query(`
                SELECT 
                    id,
                    action_type,
                    action_description,
                    author_name,
                    author_email,
                    author_role,
                    campus,
                    created_at,
                    -- Nouvelles colonnes
                    auto_evaluation_old,
                    auto_evaluation_new,
                    evaluation_tuteur_old,
                    evaluation_tuteur_new,
                    date_action_old,
                    date_action_new,
                    date_action_rre_old,
                    date_action_rre_new,
                    date_eval_tuteur_old,
                    date_eval_tuteur_new,
                    commentaire_formateur_old,
                    commentaire_formateur_new,
                    commentaire_rre_old,
                    commentaire_rre_new,
                    commentaire_old,
                    commentaire_new
                FROM [dbo].[tbl_Historique_Evaluations]
                WHERE record_id = @studentId
                ORDER BY created_at DESC
            `);

        res.json(result.recordset);
        console.log(`📜 Historique de ${studentId}:`, result.recordset.length);
    } catch (error) {
        console.error('❌ Erreur historique:', error);
        res.status(500).json({ error: 'Erreur historique' });
    }
});

// ═══════════════════════════════════════════════════════
// RÉCUPÉRER TOUTES LES ÉVALUATIONS
// ═══════════════════════════════════════════════════════
app.get('/api/evaluations', async (req, res) => {
    try {
        const effectiveUser = getEffectiveUser(req.headers);
        const { email, role, campus: userCampus, isSuperUser, isLecteur } = effectiveUser;
        const { campus, promo, student, status, sortBy, sortOrder } = req.query;

        const pool = await sql.connect(sqlConfig);
        const request = pool.request();

        let query = `
            SELECT 
                e.LOGin as id,
                e.NOM as nom,
                e.PRENOM as prenom,
                e.Campus as campus,
                e.NOM_DIP as formation,
                e.NOM_DIP as nomDip,
                e.Annee as annee,
                e.userPrincipalName as formateurEmail,
                COALESCE(ev.auto_evaluation, 'NON') as autoEvaluation,
                COALESCE(ev.evaluation_tuteur, 'NON') as evaluationTuteur,
                ev.date_action as dateAction,
                ev.date_action_rre as dateActionRRE,
                ev.commentaire_formateur as commentaireFormateur,
                ev.date_eval_tuteur as dateEvalTuteur,
                ev.commentaire_rre as commentaireRRE,
                ev.commentaire,
                ev.updated_at as lastUpdate
            FROM [dbo].[v_R_Promo_Formateur_Etudiant] e
            LEFT JOIN [dbo].[tbl_Evaluations] ev ON e.LOGin = ev.student_id
            WHERE e.LOGin IS NOT NULL
        `;

        const conditions = [];

        // 🔥 SUPER OU LECTEUR SANS USURPATION : filtrer par SON campus
        if ((isSuperUser || isLecteur) && !effectiveUser.isImpersonating) {
            if (userCampus) {
                conditions.push('e.Campus = @userCampus');
                request.input('userCampus', sql.NVarChar, userCampus);
                console.log(`🔐 ${role.toUpperCase()}: accès limité au campus`, userCampus);
            } else {
                console.log(`⚠️ ${role.toUpperCase()}: pas de campus défini, accès à tout`);
            }
        }
        // Filtrage par rôle usurpé ou réel
        else if (role === 'formateur' && email) {
            conditions.push('e.userPrincipalName = @userEmail');
            request.input('userEmail', sql.NVarChar, email);
        } else if (role === 'rre' && userCampus) {
            conditions.push('e.Campus = @userCampus');
            request.input('userCampus', sql.NVarChar, userCampus);
        }

        // Autres filtres (campus, promo, student sélectionnés dans l'interface)
        if (campus && campus !== 'tous') {
            conditions.push('e.Campus = @campus');
            request.input('campus', sql.NVarChar, campus);
        }

        if (promo && promo !== 'tous') {
            conditions.push('e.NOM_DIP = @promo');
            request.input('promo', sql.NVarChar, promo);
        }

        if (student && student !== 'tous') {
            conditions.push('e.LOGin = @student');
            request.input('student', sql.NVarChar, student);
        }

        if (conditions.length > 0) {
            query += ' AND ' + conditions.join(' AND ');
        }

        // Filtre par statut
        if (status && status !== 'tous') {
            if (status === 'OUI') {
                query += ` AND (COALESCE(ev.auto_evaluation, 'NON') = 'OUI' AND COALESCE(ev.evaluation_tuteur, 'NON') = 'OUI')`;
            } else if (status === 'PARTIEL') {
                query += ` AND (COALESCE(ev.auto_evaluation, 'NON') = 'PARTIEL' OR COALESCE(ev.evaluation_tuteur, 'NON') = 'PARTIEL')`;
            } else if (status === 'NON') {
                query += ` AND (COALESCE(ev.auto_evaluation, 'NON') = 'NON' OR COALESCE(ev.evaluation_tuteur, 'NON') = 'NON')`;
            }
        }

        // Tri
        const validSortColumns = {
            'nom': 'e.NOM, e.PRENOM',
            'campus': 'e.Campus',
            'promo': 'e.NOM_DIP',
            'formation': 'e.NOM_DIP',
            'date': 'ev.updated_at'
        };

        const orderColumn = validSortColumns[sortBy] || 'e.NOM, e.PRENOM';
        const orderDirection = sortOrder === 'desc' ? 'DESC' : 'ASC';

        query += ` ORDER BY ${orderColumn} ${orderDirection}`;

        const result = await request.query(query);

        const records = result.recordset.map(record => ({
            ...record,
            email: `${record.id}@example.com`,
            campusPromo: record.campus,
            history: []
        }));

        res.json({
            data: records
        });

        console.log(`✅ Évaluations (${role}${isSuperUser ? ' [SUPER]' : ''}${isLecteur ? ' [LECTEUR]' : ''}${effectiveUser.isImpersonating ? ' [USURPÉ]' : ''}):`, records.length, 'étudiants');
    } catch (error) {
        console.error('❌ Erreur évaluations:', error);
        res.status(500).json({ error: 'Erreur évaluations' });
    }
});

// ═══════════════════════════════════════════════════════
// RÉCUPÉRER UNE ÉVALUATION SPÉCIFIQUE
// ═══════════════════════════════════════════════════════
app.get('/api/evaluations/:studentId', async (req, res) => {
    try {
        const { studentId } = req.params;
        const userRole = req.headers['x-user-role'];
        const userEmail = req.headers['x-user-email'];
        const userCampus = req.headers['x-user-campus'];

        const pool = await sql.connect(sqlConfig);
        const request = pool.request();
        request.input('studentId', sql.NVarChar, studentId);

        let query = `
            SELECT 
                e.LOGin as id,
                e.NOM as nom,
                e.PRENOM as prenom,
                e.Campus as campus,
                e.NOM_DIP as formation,
                e.NOM_DIP as nomDip,
                e.Annee as annee,
                e.userPrincipalName as formateurEmail,
                COALESCE(ev.auto_evaluation, 'NON') as autoEvaluation,
                COALESCE(ev.evaluation_tuteur, 'NON') as evaluationTuteur,
                ev.date_action as dateAction,
                ev.date_action_rre as dateActionRRE,
                ev.commentaire_formateur as commentaireFormateur,
                ev.date_eval_tuteur as dateEvalTuteur,
                ev.commentaire_rre as commentaireRRE,
                ev.commentaire,
                ev.updated_at as lastUpdate
            FROM [dbo].[v_R_Promo_Formateur_Etudiant] e
            LEFT JOIN [dbo].[tbl_Evaluations] ev ON e.LOGin = ev.student_id
            WHERE e.LOGin = @studentId
        `;

        if (userRole === 'formateur' && userEmail) {
            query += ` AND e.userPrincipalName = @userEmail`;
            request.input('userEmail', sql.NVarChar, userEmail);
        } else if ((userRole === 'rre' || userRole === 'super' || userRole === 'lecteur') && userCampus) {
            query += ` AND e.Campus = @userCampus`;
            request.input('userCampus', sql.NVarChar, userCampus);
        }

        const evalResult = await request.query(query);

        if (evalResult.recordset.length === 0) {
            return res.status(404).json({ error: 'Étudiant non trouvé ou non autorisé' });
        }

        const record = evalResult.recordset[0];

        const historyResult = await pool.request()
            .input('studentId', sql.NVarChar, studentId)
            .query(`
                SELECT 
                    action_type as action,
                    action_description as details,
                    author_name as author,
                    created_at as date
                FROM [dbo].[tbl_Historique_Evaluations]
                WHERE record_id = @studentId
                ORDER BY created_at DESC
            `);

        res.json({
            ...record,
            email: `${record.id}@example.com`,
            campusPromo: record.campus,
            history: historyResult.recordset
        });

        console.log('✅ Détail étudiant envoyé:', studentId);
    } catch (error) {
        console.error('❌ Erreur détail évaluation:', error);
        res.status(500).json({ error: 'Erreur détail évaluation' });
    }
});

// ═══════════════════════════════════════════════════════
// METTRE À JOUR UNE ÉVALUATION (VERSION CORRIGÉE)
// Historique : enregistre TOUTES les valeurs à chaque action
// ═══════════════════════════════════════════════════════
app.put('/api/evaluations/:studentId', async (req, res) => {
    try {
        const { studentId } = req.params;
        const updates = req.body.updates;
        const author = req.body.author;

        const effectiveUser = getEffectiveUser(req.headers);
        const { email, role, campus, isSuperUser, isLecteur } = effectiveUser;

        // 🔥 BLOQUER LES LECTEURS
        if (isLecteur) {
            console.log(`🚫 Tentative de modification refusée: ${email} (lecteur)`);
            return res.status(403).json({
                error: 'Vous n\'avez pas les droits de modification',
                message: 'Votre rôle est en lecture seule'
            });
        }

        const pool = await sql.connect(sqlConfig);

        // Vérification des accès (sauf super-user)
        if (!isSuperUser) {
            if (role === 'formateur' && email) {
                const accessCheck = await pool.request()
                    .input('studentId', sql.NVarChar, studentId)
                    .input('userEmail', sql.NVarChar, email)
                    .query(`
                        SELECT COUNT(*) as count 
                        FROM [dbo].[v_R_Promo_Formateur_Etudiant]
                        WHERE LOGin = @studentId AND userPrincipalName = @userEmail
                    `);

                if (accessCheck.recordset[0].count === 0) {
                    console.log(`🚫 Accès refusé: ${email} n'a pas accès à ${studentId}`);
                    return res.status(403).json({ error: 'Accès non autorisé à cet étudiant' });
                }
            } else if (role === 'rre' && campus) {
                const accessCheck = await pool.request()
                    .input('studentId', sql.NVarChar, studentId)
                    .input('userCampus', sql.NVarChar, campus)
                    .query(`
                        SELECT COUNT(*) as count 
                        FROM [dbo].[v_R_Promo_Formateur_Etudiant]
                        WHERE LOGin = @studentId AND Campus = @userCampus
                    `);

                if (accessCheck.recordset[0].count === 0) {
                    console.log(`🚫 Accès refusé: RRE ${email} n'a pas accès à ${studentId}`);
                    return res.status(403).json({ error: 'Accès non autorisé à cet étudiant' });
                }
            }
        } else {
            console.log(`🎭 SUPER-USER en action: ${email} modifie ${studentId}`);
        }

        // Récupérer l'enregistrement actuel
        const currentResult = await pool.request()
            .input('studentId', sql.NVarChar, studentId)
            .query(`SELECT * FROM [dbo].[tbl_Evaluations] WHERE student_id = @studentId`);

        const currentRecord = currentResult.recordset[0];

        // ═══════════════════════════════════════════════════════
        // CAS 1 : CRÉATION
        // ═══════════════════════════════════════════════════════
        if (!currentRecord) {
            const studentInfo = await pool.request()
                .input('studentId', sql.NVarChar, studentId)
                .query(`
                    SELECT TOP 1 LOGin, NOM, PRENOM, Campus, NOM_DIP, Annee
                    FROM [dbo].[v_R_Promo_Formateur_Etudiant]
                    WHERE LOGin = @studentId
                `);

            if (studentInfo.recordset.length === 0) {
                return res.status(404).json({ error: 'Étudiant non trouvé' });
            }

            const student = studentInfo.recordset[0];
            const today = new Date().toISOString().split('T')[0];

            await pool.request()
                .input('student_id', sql.NVarChar, studentId)
                .input('nom', sql.NVarChar, student.NOM || '')
                .input('prenom', sql.NVarChar, student.PRENOM || '')
                .input('campus', sql.NVarChar, student.Campus || '')
                .input('formation', sql.NVarChar, student.NOM_DIP || '')
                .input('promo_nom_dip', sql.NVarChar, student.NOM_DIP || '')
                .input('annee', sql.NVarChar, String(student.Annee ?? ''))
                .input('auto_eval', sql.NVarChar, updates.autoEvaluation || 'NON')
                .input('eval_tuteur', sql.NVarChar, updates.evaluationTuteur || 'NON')
                .input('date_action', sql.Date, updates.dateAction || (role === 'formateur' || isSuperUser ? today : null))
                .input('date_action_rre', sql.Date, updates.dateActionRRE || (role === 'rre' || isSuperUser ? today : null))
                .input('commentaire_formateur', sql.NVarChar, updates.commentaireFormateur || null)
                .input('date_eval_tuteur', sql.Date, updates.dateEvalTuteur || null)
                .input('commentaire_rre', sql.NVarChar, updates.commentaireRRE || null)
                .input('commentaire', sql.NVarChar, updates.commentaire || null)
                .input('created_by', sql.NVarChar, author.email)
                .query(`
                    INSERT INTO [dbo].[tbl_Evaluations]
                    (student_id, nom, prenom, campus, formation, promo_nom_dip, annee, 
                     auto_evaluation, evaluation_tuteur, date_action, date_action_rre,
                     commentaire_formateur, date_eval_tuteur, commentaire_rre, 
                     commentaire, created_by, updated_by)
                    VALUES
                    (@student_id, @nom, @prenom, @campus, @formation, @promo_nom_dip, @annee,
                     @auto_eval, @eval_tuteur, @date_action, @date_action_rre,
                     @commentaire_formateur, @date_eval_tuteur, @commentaire_rre, 
                     @commentaire, @created_by, @created_by)
                `);

            // Log historique complet pour la création
            await logHistoryComplete({
                record_id: studentId,
                action_type: 'CREATION',
                action_description: `Création du dossier d'évaluation${isSuperUser ? ' [SUPER-USER]' : ''}`,
                author_email: author.email,
                author_name: author.name,
                author_role: author.role,
                campus: student.Campus,
                auto_evaluation_new: updates.autoEvaluation || 'NON',
                evaluation_tuteur_new: updates.evaluationTuteur || 'NON',
                date_action_new: updates.dateAction || (role === 'formateur' || isSuperUser ? today : null),
                date_action_rre_new: updates.dateActionRRE || (role === 'rre' || isSuperUser ? today : null),
                commentaire_formateur_new: updates.commentaireFormateur || null,
                date_eval_tuteur_new: updates.dateEvalTuteur || null,
                commentaire_rre_new: updates.commentaireRRE || null,
                commentaire_new: updates.commentaire || null
            });

            const createdResult = await pool.request()
                .input('studentId', sql.NVarChar, studentId)
                .query(`
                    SELECT 
                        student_id as id, nom, prenom, campus, formation,
                        promo_nom_dip as nomDip, annee,
                        auto_evaluation as autoEvaluation,
                        evaluation_tuteur as evaluationTuteur,
                        date_action as dateAction,
                        date_action_rre as dateActionRRE,
                        commentaire_formateur as commentaireFormateur,
                        date_eval_tuteur as dateEvalTuteur,
                        commentaire_rre as commentaireRRE,
                        commentaire, updated_at as lastUpdate
                    FROM [dbo].[tbl_Evaluations]
                    WHERE student_id = @studentId
                `);

            console.log('✅ Nouvelle évaluation créée:', studentId);
            return res.json({
                success: true,
                message: 'Évaluation créée',
                data: createdResult.recordset[0]
            });
        }

        // ═══════════════════════════════════════════════════════
        // CAS 2 : MISE À JOUR
        // ═══════════════════════════════════════════════════════
        let updateQuery = 'UPDATE [dbo].[tbl_Evaluations] SET updated_at = GETDATE(), updated_by = @updated_by';
        const request = pool.request()
            .input('studentId', sql.NVarChar, studentId)
            .input('updated_by', sql.NVarChar, author.email);

        let hasChanges = false;

        const canEditFormateur = role === 'formateur' || isSuperUser;
        const canEditRRE = role === 'rre' || isSuperUser;

        // ── Construire les valeurs finales (après mise à jour) ──
        // On part des valeurs actuelles et on applique les modifications
        let finalAutoEval = currentRecord.auto_evaluation || 'NON';
        let finalEvalTuteur = currentRecord.evaluation_tuteur || 'NON';
        let finalDateAction = currentRecord.date_action
            ? currentRecord.date_action.toISOString().split('T')[0]
            : null;
        let finalDateActionRRE = currentRecord.date_action_rre
            ? currentRecord.date_action_rre.toISOString().split('T')[0]
            : null;
        let finalDateEvalTuteur = currentRecord.date_eval_tuteur
            ? currentRecord.date_eval_tuteur.toISOString().split('T')[0]
            : null;
        let finalCommentaireFormateur = currentRecord.commentaire_formateur || null;
        let finalCommentaireRRE = currentRecord.commentaire_rre || null;
        let finalCommentaire = currentRecord.commentaire || null;

        // Auto-évaluation
        if (canEditFormateur && updates.autoEvaluation !== undefined && updates.autoEvaluation !== currentRecord.auto_evaluation) {
            updateQuery += ', auto_evaluation = @auto_eval';
            request.input('auto_eval', sql.NVarChar, updates.autoEvaluation);
            finalAutoEval = updates.autoEvaluation;
            hasChanges = true;
        }

        // Évaluation tuteur
        if (canEditFormateur && updates.evaluationTuteur !== undefined && updates.evaluationTuteur !== currentRecord.evaluation_tuteur) {
            updateQuery += ', evaluation_tuteur = @eval_tuteur';
            request.input('eval_tuteur', sql.NVarChar, updates.evaluationTuteur);
            finalEvalTuteur = updates.evaluationTuteur;
            hasChanges = true;
        }

        // Date action formateur
        if (canEditFormateur) {
            if (updates.autoEvaluation !== undefined ||
                updates.evaluationTuteur !== undefined ||
                updates.commentaireFormateur !== undefined ||
                updates.dateEvalTuteur !== undefined ||
                updates.commentaire !== undefined ||
                updates.dateAction !== undefined) {

                const today = updates.dateAction || new Date().toISOString().split('T')[0];
                const currentDateAction = currentRecord.date_action
                    ? currentRecord.date_action.toISOString().split('T')[0]
                    : null;

                if (currentDateAction !== today) {
                    updateQuery += ', date_action = @date_action';
                    request.input('date_action', sql.Date, today);
                    finalDateAction = today;
                    hasChanges = true;
                }
            }
        }

        // Commentaire formateur
        if (canEditFormateur && updates.commentaireFormateur !== undefined && updates.commentaireFormateur !== currentRecord.commentaire_formateur) {
            updateQuery += ', commentaire_formateur = @commentaire_formateur';
            request.input('commentaire_formateur', sql.NVarChar, updates.commentaireFormateur || null);
            finalCommentaireFormateur = updates.commentaireFormateur || null;
            hasChanges = true;
        }

        // Date évaluation tuteur
        if (canEditFormateur && updates.dateEvalTuteur !== undefined) {
            const currentDateEvalTuteur = currentRecord.date_eval_tuteur
                ? currentRecord.date_eval_tuteur.toISOString().split('T')[0]
                : null;
            const newDateEvalTuteur = updates.dateEvalTuteur || null;

            if (currentDateEvalTuteur !== newDateEvalTuteur) {
                updateQuery += ', date_eval_tuteur = @date_eval_tuteur';
                request.input('date_eval_tuteur', sql.Date, newDateEvalTuteur);
                finalDateEvalTuteur = newDateEvalTuteur;
                hasChanges = true;
            }
        }

        // Date action RRE
        if (canEditRRE) {
            if ((updates.commentaireRRE !== undefined && updates.commentaireRRE.trim() !== '') || updates.dateActionRRE !== undefined) {
                const today = updates.dateActionRRE || new Date().toISOString().split('T')[0];
                const currentDateActionRRE = currentRecord.date_action_rre
                    ? currentRecord.date_action_rre.toISOString().split('T')[0]
                    : null;

                if (currentDateActionRRE !== today) {
                    updateQuery += ', date_action_rre = @date_action_rre';
                    request.input('date_action_rre', sql.Date, today);
                    finalDateActionRRE = today;
                    hasChanges = true;
                }
            }
        }

        // Commentaire RRE
        if (canEditRRE && updates.commentaireRRE !== undefined && updates.commentaireRRE !== currentRecord.commentaire_rre) {
            updateQuery += ', commentaire_rre = @commentaire_rre';
            request.input('commentaire_rre', sql.NVarChar, updates.commentaireRRE || null);
            finalCommentaireRRE = updates.commentaireRRE || null;
            hasChanges = true;
        }

        // Commentaire général
        if (updates.commentaire !== undefined && updates.commentaire !== currentRecord.commentaire) {
            updateQuery += ', commentaire = @commentaire';
            request.input('commentaire', sql.NVarChar, updates.commentaire || null);
            finalCommentaire = updates.commentaire || null;
            hasChanges = true;
        }

        // Exécuter la mise à jour et l'historique
        if (hasChanges) {
            updateQuery += ' WHERE student_id = @studentId';
            await request.query(updateQuery);

            // ═══════════════════════════════════════════════════════
            // 🔥 HISTORIQUE : on enregistre TOUTES les valeurs finales
            // (pas seulement les champs modifiés)
            // Comme ça chaque ligne d'historique est complète
            // ═══════════════════════════════════════════════════════
            await logHistoryComplete({
                record_id: studentId,
                action_type: 'Nouvelle saisie',
                action_description: `Mise à jour de l'évaluation${isSuperUser ? ' [SUPER-USER]' : ''}`,
                author_email: author.email,
                author_name: author.name,
                author_role: author.role,
                campus: author.campus,
                // Toujours remplir TOUTES les colonnes _new avec l'état final
                auto_evaluation_old: currentRecord.auto_evaluation || null,
                auto_evaluation_new: finalAutoEval,
                evaluation_tuteur_old: currentRecord.evaluation_tuteur || null,
                evaluation_tuteur_new: finalEvalTuteur,
                date_action_old: currentRecord.date_action || null,
                date_action_new: finalDateAction,
                date_action_rre_old: currentRecord.date_action_rre || null,
                date_action_rre_new: finalDateActionRRE,
                date_eval_tuteur_old: currentRecord.date_eval_tuteur || null,
                date_eval_tuteur_new: finalDateEvalTuteur,
                commentaire_formateur_old: currentRecord.commentaire_formateur || null,
                commentaire_formateur_new: finalCommentaireFormateur,
                commentaire_rre_old: currentRecord.commentaire_rre || null,
                commentaire_rre_new: finalCommentaireRRE,
                commentaire_old: currentRecord.commentaire || null,
                commentaire_new: finalCommentaire
            });

            console.log(`✅ Évaluation mise à jour: ${studentId}${isSuperUser ? ' [SUPER-USER]' : ''}`);
        } else {
            console.log('ℹ️ Aucune modification détectée pour:', studentId);
        }

        // Récupérer et renvoyer l'enregistrement mis à jour
        const updatedResult = await pool.request()
            .input('studentId', sql.NVarChar, studentId)
            .query(`
                SELECT 
                    student_id as id, nom, prenom, campus, formation,
                    promo_nom_dip as nomDip, annee,
                    auto_evaluation as autoEvaluation,
                    evaluation_tuteur as evaluationTuteur,
                    date_action as dateAction,
                    date_action_rre as dateActionRRE,
                    commentaire_formateur as commentaireFormateur,
                    date_eval_tuteur as dateEvalTuteur,
                    commentaire_rre as commentaireRRE,
                    commentaire, updated_at as lastUpdate
                FROM [dbo].[tbl_Evaluations]
                WHERE student_id = @studentId
            `);

        res.json({
            success: true,
            message: 'Évaluation mise à jour',
            data: updatedResult.recordset[0]
        });
    } catch (error) {
        console.error('❌ Erreur mise à jour:', error);
        res.status(500).json({ error: 'Erreur mise à jour', details: error.message });
    }
});

// ═══════════════════════════════════════════════════════
// DÉMARRAGE
// ═══════════════════════════════════════════════════════
app.listen(3005, () => {
    console.log('\n🚀 Backend démarré sur port 3005');
    console.log('📡 Routes disponibles:');
    console.log('   POST /auth/verify');
    console.log('   GET  /api/campus-list');
    console.log('   GET  /api/student-list?campus=XXX&promo=XXX');
    console.log('   GET  /api/promo-list?campus=XXX');
    console.log('   GET  /api/promo-data');
    console.log('   GET  /api/evaluations');
    console.log('   GET  /api/evaluations/:studentId');
    console.log('   GET  /api/history/:studentId');
    console.log('   PUT  /api/evaluations/:studentId');
    console.log('\n📋 Règles d\'accès:');
    console.log('   - Lecteur: voit uniquement SON campus (LECTURE SEULE)');
    console.log('   - Super: voit et modifie uniquement SON campus');
    console.log('   - Formateur: voit uniquement SES étudiants');
    console.log('   - RRE: voit uniquement les étudiants de SON campus');
    console.log('\n📜 Historique: UNE LIGNE PAR ACTION avec TOUTES les valeurs\n');
});