'https://ainur.iut-fbleau.fr/auth/login?service=https%3A%2F%2Fnotes.iut-fbleau.fr%2Fservices%2FdoAuth.php%3Fhref%3Dhttps%3A%2F%2Fnotes.iut-fbleau.fr%2F',
    'url_data_prefix' => 'https://notes.iut-fbleau.fr/services/data.php?q=relev%C3%A9Etudiant&semestre=',
    'semestre_mapping' => [
		'BUT2FI_S1' => '154',
		'BUT2FI_S2' => '248',
		'BUT2FI_S3' => '263',
		'BUT2FI_S4' => '351',
        'BUT2FA_S1' => '154',
        'BUT2FA_S2' => '248',
        'BUT2FA_S3' => '265'
    ]
];
// Couleurs pour les UEs
$ue_colors = [
    'UE.1.1' => '#b80004',
    'UE.1.2' => '#f97b3d',
    'UE.1.3' => '#feb40b',
    'UE.1.4' => '#80cb3f',
    'UE.1.5' => '#05162e',
    'UE.1.6' => '#548687',
    'UE.2.1' => '#b80004',
    'UE.2.2' => '#f97b3d',
    'UE.2.3' => '#feb40b',
    'UE.2.4' => '#80cb3f',
    'UE.2.5' => '#05162e',
    'UE.2.6' => '#548687',
    'UE.3.1' => '#b80004',
    'UE.3.2' => '#f97b3d',
    'UE.3.3' => '#feb40b',
    'UE.3.4' => '#80cb3f',
    'UE.3.5' => '#05162e',
    'UE.3.6' => '#548687'
];
// Fonction pour se connecter et récupérer les données
function fetchData($username, $password, $formation, $semestre) {
    global $config;
    
    // Vérifier si un semestre est sélectionné
    if (!isset($semestre)) {
        return ['error' => 'Semestre non valide'];
    }
    
    // Initialiser cURL pour simuler le navigateur
    $ch = curl_init();
    $cookie_file = tempnam(sys_get_temp_dir(), 'cookies');
    
    // Configuration initiale de cURL avec un User-Agent de navigateur
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    
    // 1. Récupérer le formulaire de login pour obtenir les tokens potentiels
    curl_setopt($ch, CURLOPT_URL, $config['url_login']);
    $login_page = curl_exec($ch);
    
    if ($login_page === false) {
        return ['error' => 'Impossible de se connecter au serveur: ' . curl_error($ch)];
    }
    
    // Extraire le token CSRF ou lt/execution s'ils existent
    $lt_token = '';
    $execution_token = '';
    
    // Chercher lt et execution dans le formulaire CAS
    if (preg_match('/ $username,
        'password' => $password,
        'submitBtn' => 'Connexion'
    ];
    
    // Ajouter les tokens s'ils existent
    if (!empty($lt_token)) {
        $post_data['lt'] = $lt_token;
    }
    
    if (!empty($execution_token)) {
        $post_data['execution'] = $execution_token;
        $post_data['_eventId'] = 'submit'; // Souvent utilisé avec 'execution'
    }
    
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
    
    // Configurer les en-têtes pour simuler une requête de formulaire
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/x-www-form-urlencoded',
        'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
        'Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7',
        'Referer: ' . $config['url_login']
    ]);
    
    $response_post = curl_exec($ch);
    
    if ($response_post === false) {
        return ['error' => 'Échec de la connexion: ' . curl_error($ch)];
    }
    
    // La redirection devrait nous amener à la page du bulletin
    // Vérifier l'URL actuelle après redirection
    $current_url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
    
    // Aller directement à la page des notes après l'authentification
    curl_setopt($ch, CURLOPT_URL, 'https://notes.iut-fbleau.fr/');
    curl_setopt($ch, CURLOPT_POST, false);
    $bulletin_page = curl_exec($ch);
    
    if ($bulletin_page === false) {
        return ['error' => 'Impossible d\'accéder à la page des notes: ' . curl_error($ch)];
    }
    
    // Vérifier si la connexion a réussi
    if (strpos($bulletin_page, "Ce relevé de notes est provisoire") === false && 
        strpos($bulletin_page, "ScoDoc") === false) {
        return ['error' => 'Identifiants incorrects ou problème de connexion'];
    }
    
    // 3. Récupérer les données JSON
    $data_url = $config['url_data_prefix'] . $semestre;
    curl_setopt($ch, CURLOPT_URL, $data_url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Accept: application/json',
        'Referer: https://notes.iut-fbleau.fr/'
    ]);
    $json_response = curl_exec($ch);
    
    curl_close($ch);
    
    if ($json_response === false) {
        return ['error' => 'Impossible de récupérer les données'];
    }
    
    // Décoder les données JSON
    $data = json_decode($json_response, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        return ['error' => 'Format de données invalide: ' . json_last_error_msg()];
    }
    
    return $data;
}
// Simuler les données pour le débogage
function getSimulatedData() {
    // Détecter si un fichier data.json existe localement
    if (file_exists('data.json')) {
        $json_data = file_get_contents('data.json');
        return json_decode($json_data, true);
    }
    
    // Structure simplifiée des données simulées
    return [
        'relevé' => [
            'etudiant' => [
                'nom' => 'DUPONT',
                'prenom' => 'Jean'
            ],
            'formation' => [
                'acronyme' => 'BUT INFO'
            ],
            'semestre' => [
                'numero' => 2,
                'notes' => [
                    'value' => '14.50',
                    'min' => '6.75',
                    'max' => '16.20',
                    'moy' => '12.35'
                ],
                'rang' => [
                    'value' => '5',
                    'total' => '86'
                ]
            ],
            'ues' => [
                'UE.1.1' => [
                    'titre' => 'Développer des applications',
                    'moyenne' => [
                        'value' => '15.75',
                        'min' => '7.50',
                        'max' => '18.00',
                        'moy' => '13.25',
                        'rang' => '4',
                        'total' => '86'
                    ],
                    'ressources' => [
                        'R1.01' => [
                            'coef' => 42,
                            'moyenne' => '16.50'
                        ],
                        'R1.02' => [
                            'coef' => 18,
                            'moyenne' => '15.00'
                        ]
                    ],
                    'saes' => [
                        'S1.01' => [
                            'coef' => 40,
                            'moyenne' => '16.00'
                        ]
                    ]
                ],
                'UE.1.2' => [
                    'titre' => 'Optimiser des applications',
                    'moyenne' => [
                        'value' => '14.00',
                        'min' => '6.00',
                        'max' => '17.50',
                        'moy' => '12.00',
                        'rang' => '8',
                        'total' => '86'
                    ],
                    'ressources' => [
                        'R1.03' => [
                            'coef' => 24,
                            'moyenne' => '14.50'
                        ],
                        'R1.04' => [
                            'coef' => 16,
                            'moyenne' => '13.50'
                        ]
                    ],
                    'saes' => [
                        'S1.02' => [
                            'coef' => 40,
                            'moyenne' => '15.00'
                        ]
                    ]
                ]
            ],
            'ressources' => [
                'R1.01' => [
                    'titre' => 'Initiation au développement',
                    'evaluations' => [
                        [
                            'id' => 1001,
                            'description' => 'TP noté 1',
                            'date' => '2023-10-15T10:00:00+02:00',
                            'note' => [
                                'value' => '17.00',
                                'min' => '8.00',
                                'max' => '19.00',
                                'moy' => '14.50'
                            ],
                            'coef' => '1.00'
                        ],
                        [
                            'id' => 1002,
                            'description' => 'Examen final',
                            'date' => '2023-12-20T14:00:00+01:00',
                            'note' => [
                                'value' => '16.00',
                                'min' => '7.00',
                                'max' => '18.50',
                                'moy' => '13.75'
                            ],
                            'coef' => '2.00'
                        ]
                    ]
                ],
                'R1.02' => [
                    'titre' => 'Programmation orientée objet',
                    'evaluations' => [
                        [
                            'id' => 1003,
                            'description' => 'Projet',
                            'date' => '2023-11-10T10:00:00+01:00',
                            'note' => [
                                'value' => '15.00',
                                'min' => '9.00',
                                'max' => '18.00',
                                'moy' => '14.00'
                            ],
                            'coef' => '1.50'
                        ]
                    ]
                ],
                'R1.03' => [
                    'titre' => 'Architecture des systèmes',
                    'evaluations' => [
                        [
                            'id' => 1004,
                            'description' => 'Contrôle',
                            'date' => '2023-10-05T08:00:00+02:00',
                            'note' => [
                                'value' => '14.50',
                                'min' => '6.00',
                                'max' => '17.00',
                                'moy' => '12.00'
                            ],
                            'coef' => '1.00'
                        ]
                    ]
                ],
                'R1.04' => [
                    'titre' => 'Systèmes d\'exploitation',
                    'evaluations' => [
                        [
                            'id' => 1005,
                            'description' => 'TP noté',
                            'date' => '2023-11-25T14:00:00+01:00',
                            'note' => [
                                'value' => '13.50',
                                'min' => '7.50',
                                'max' => '16.50',
                                'moy' => '12.50'
                            ],
                            'coef' => '1.00'
                        ]
                    ]
                ]
            ],
            'saes' => [
                'S1.01' => [
                    'titre' => 'Implémentation d\'un besoin client',
                    'evaluations' => [
                        [
                            'id' => 2001,
                            'description' => 'Livrable',
                            'date' => '2023-12-10T10:00:00+01:00',
                            'note' => [
                                'value' => '16.00',
                                'min' => '8.50',
                                'max' => '18.00',
                                'moy' => '13.75'
                            ],
                            'coef' => '1.00'
                        ]
                    ]
                ],
                'S1.02' => [
                    'titre' => 'Comparaison d\'approches algorithmiques',
                    'evaluations' => [
                        [
                            'id' => 2002,
                            'description' => 'Rapport',
                            'date' => '2023-11-30T16:00:00+01:00',
                            'note' => [
                                'value' => '15.00',
                                'min' => '7.00',
                                'max' => '17.50',
                                'moy' => '12.50'
                            ],
                            'coef' => '1.00'
                        ]
                    ]
                ]
            ]
        ]
    ];
}
// Analyser les statistiques globales
function calculateOverallStats($data) {
    $allGrades = [];
    
    // Récupérer toutes les notes des ressources
    foreach ($data['relevé']['ressources'] as $resource) {
        foreach ($resource['evaluations'] as $eval) {
            if (isset($eval['note']['value'])) {
                $allGrades[] = (float)$eval['note']['value'];
            }
        }
    }
    
    // Récupérer toutes les notes des SAEs
    foreach ($data['relevé']['saes'] as $sae) {
        foreach ($sae['evaluations'] as $eval) {
            if (isset($eval['note']['value'])) {
                $allGrades[] = (float)$eval['note']['value'];
            }
        }
    }
    
    // Calculer les statistiques
    $min = !empty($allGrades) ? min($allGrades) : 0;
    $max = !empty($allGrades) ? max($allGrades) : 0;
    $avg = !empty($allGrades) ? array_sum($allGrades) / count($allGrades) : 0;
    $below10Count = count(array_filter($allGrades, function($grade) { return $grade < 10; }));
    $above15Count = count(array_filter($allGrades, function($grade) { return $grade >= 15; }));
    
    return [
        'count' => count($allGrades),
        'min' => number_format($min, 2),
        'max' => number_format($max, 2),
        'avg' => number_format($avg, 2),
        'below10Percent' => !empty($allGrades) ? number_format(($below10Count / count($allGrades)) * 100, 1) : 0,
        'above15Percent' => !empty($allGrades) ? number_format(($above15Count / count($allGrades)) * 100, 1) : 0
    ];
}
// Traiter la demande de connexion
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username'], $_POST['password'], $_POST['formation'])) {
    $username = $_POST['username'];
    $password = $_POST['password'];
    $formation = $_POST['formation'];
    // Déterminer le semestre à utiliser
    $semestre = isset($config['semestre_mapping'][$formation]) ? $config['semestre_mapping'][$formation] : null;
    
    // Vérifier si le mode de simulation est activé
    if ($username === 'demo' && $password === 'demo') {
        $result = getSimulatedData();
        $simulation_mode = true;
    } else {
        $result = fetchData($username, $password, $formation, $semestre);
        $simulation_mode = false;
    }
    
    if (isset($result['error'])) {
        $error_message = $result['error'];
    } else {
        // Stocker les données dans la session
        $_SESSION['bulletin_data'] = $result;
        $_SESSION['username'] = $username;
        $_SESSION['formation'] = $formation;
        $_SESSION['simulation_mode'] = $simulation_mode;
        
        // Rediriger vers la page du bulletin
        header('Location: ' . $_SERVER['PHP_SELF'] . '?view=dashboard');
        exit;
    }
}
// Déconnexion
if (isset($_GET['logout'])) {
    session_unset();
    session_destroy();
    header('Location: ' . $_SERVER['PHP_SELF']);
    exit;
}
// Récupérer la vue actuelle (dashboard ou login)
$current_view = isset($_GET['view']) && $_GET['view'] === 'dashboard' && isset($_SESSION['bulletin_data']) ? 'dashboard' : 'login';
// Récupérer l'onglet actif
$active_tab = isset($_GET['tab']) ? $_GET['tab'] : 'overview';
// Si on est sur le dashboard, calculer les statistiques
if ($current_view === 'dashboard') {
    $data = $_SESSION['bulletin_data'];
    $stats = calculateOverallStats($data);
}
?>
    
    
    Dashboard de Bulletins BUT
    
    
    
    
        
        
            
                Connexion à votre bulletin
                
                
                    
                        
                    
                
                
                
             
         
    
        
        
            
                
                    
                        Dashboard 
                    
                    
                         
                        - Semestre 
                    
                    
                        Mode simulation - Données non réelles
                    
                 
                
                    /20
                    Moyenne générale
                    
                        Rang : /
                    
                    Déconnexion
                 
             
        
        
        
        
        
            
                
                
                    
                        
                     
                    
                    
                    
                        
                        
                            
                                
Performance par UE
                                
                            
                            
                         
                        
                        
                            
                                
Profil de compétences
                                
                            
                            
                         
                     
                    
                        
                        
                            Meilleures performances
                            
                                 $resource) {
                                    foreach ($resource['evaluations'] as $eval) {
                                        if (isset($eval['note']['value'])) {
                                            $allEvals[] = [
                                                'resourceId' => $resourceId,
                                                'resourceTitle' => $resource['titre'],
                                                'evalId' => $eval['id'],
                                                'description' => $eval['description'],
                                                'note' => (float)$eval['note']['value'],
                                                'coef' => (float)$eval['coef']
                                            ];
                                        }
                                    }
                                }
                                
                                foreach ($data['relevé']['saes'] as $saeId => $sae) {
                                    foreach ($sae['evaluations'] as $eval) {
                                        if (isset($eval['note']['value'])) {
                                            $allEvals[] = [
                                                'resourceId' => $saeId,
                                                'resourceTitle' => $sae['titre'],
                                                'evalId' => $eval['id'],
                                                'description' => $eval['description'],
                                                'note' => (float)$eval['note']['value'],
                                                'coef' => (float)$eval['coef']
                                            ];
                                        }
                                    }
                                }
                                
                                // Trier par note (décroissant)
                                usort($allEvals, function($a, $b) {
                                    return $b['note'] <=> $a['note'];
                                });
                                
                                // Afficher les 5 meilleures
                                $bestEvals = array_slice($allEvals, 0, 5);
                                
                                foreach ($bestEvals as $eval):
                                ?>
                                    
                                
                             
                        
                        
                            Performances à améliorer
                            
                                 $b['note'];
                                });
                                
                                // Afficher les 5 moins bonnes
                                $worstEvals = array_slice($allEvals, 0, 5);
                                
                                foreach ($worstEvals as $eval):
                                ?>
                                    
                                
                             
                     
                    
                    
                        
                            
Distribution des notes
                            
                        
                        
                     
                 
            
                
                
                    
                        
Performances par UE
                        
                    
                    
                    
                    
                        Détails des unités d'enseignement
                        
                             $ue): ?>
                                
                                    
                                        
                                        
                                        
                                        
                                        
                                            Ressources
                                            
                                                
                                                     $resourceInfo): ?>
                                                        
                                                        
                                                            
                                                            /20
                                                        
                                                    
                                                
                                                    Aucune ressource associée
                                                
                                            SAEs
                                            
                                                
                                                     $saeInfo): ?>
                                                        
                                                        
                                                            
                                                            /20
                                                        
                                                    
                                                
                                                    Aucune SAE associée
                                                
                                             
                                     
                                 
                            
                         
                 
            
                
                
            
                
                
                    Situations d'Apprentissage et d'Évaluation
                    
                         $sae): ?>
                             $ue) {
                                if (isset($ue['saes']) && array_key_exists($saeId, $ue['saes'])) {
                                    $linkedUEs[] = $ueId;
                                }
                            }
                            ?>
                            
                        
                     
            
                
                
                    
                        
Évolution des notes
                        
                    
                    
                    
                    Historique des évaluations
                    
                        
                             $resource) {
                                foreach ($resource['evaluations'] as $eval) {
                                    if (isset($eval['date']) && $eval['date']) {
                                        $gradesOverTime[] = [
                                            'date' => new DateTime($eval['date']),
                                            'name' => $resourceId . ' - ' . $eval['description'],
                                            'grade' => (float)$eval['note']['value'],
                                            'type' => 'resource'
                                        ];
                                    }
                                }
                            }
                            
                            foreach ($data['relevé']['saes'] as $saeId => $sae) {
                                foreach ($sae['evaluations'] as $eval) {
                                    if (isset($eval['date']) && $eval['date']) {
                                        $gradesOverTime[] = [
                                            'date' => new DateTime($eval['date']),
                                            'name' => $saeId . ' - ' . $eval['description'],
                                            'grade' => (float)$eval['note']['value'],
                                            'type' => 'sae'
                                        ];
                                    }
                                }
                            }
                            
                            // Trier par date
                            usort($gradesOverTime, function($a, $b) {
                                return $a['date'] <=> $b['date'];
                            });
                            
                            foreach ($gradesOverTime as $index => $event):
                                $colorClass = $event['grade'] >= 16 ? 'bg-green-500' : ($event['grade'] >= 10 ? 'bg-blue-500' : 'bg-red-500');
                            ?>
                                - 
                                    
                                
 
                 
            
                
                
                    Comparaison d'éléments
                    
                    
                        
                    
                    
                    
                    
                    
                        Éléments sélectionnés
                        
                            Aucun élément sélectionné pour la comparaison
                         
                     
                    
                    
                        
                            
Graphique de comparaison