<?php session_start(); ?>
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="w3.css">
<link href="https://fonts.googleapis.com/css2?family=Playfair+Display:wght@600;700&family=Source+Sans+3:wght@300;400;600&display=swap" rel="stylesheet">
<title>Bulletin de Notes</title>
<style>

/* ══════════════════════════════════════════════════════════════
   PRINT — identical look to original, clean black-on-white
   ══════════════════════════════════════════════════════════════ */
@media print {
    .noprint              { display: none !important; }
    .page-break           { display: block; page-break-after: always; page-break-inside: avoid; }
    @page                 { size: 210mm 297mm; margin: 7mm; }
    body                  { background: #fff !important; font-family: "Times New Roman", Times, serif; font-size: 12px; }

    /* Grade color → bold only in print (ink-friendly) */
    .g-high               { font-weight: bold; }
    .g-low                { font-weight: bold; }

    /* Rang row: hidden by default, shown when .visible is toggled before print */
    tr.rang-row           { display: none; }
    tr.rang-row.visible   { display: table-row !important; }
    tr.moy-classe-row     { display: none; }
    tr.moy-classe-row.visible { display: table-row !important; }
    tr.mention-row        { display: none; }
    tr.mention-row.visible { display: table-row !important; }

    /* Strip screen decorations */
    .bulletin-card        { box-shadow: none !important; border-radius: 0 !important; padding: 0 !important; margin-bottom: 0 !important; }
    .bulletin-wrap        { padding: 0 !important; }
    .bul-table, .obs-table { border-collapse: collapse; }
    .bul-table td, .bul-table th,
    .obs-table td          { border: 1px solid #000 !important; }

    /* Row tints → white in print */
    tr.mat-header td,
    tr.total-row td,
    tr.moy-mat-row td,
    tr.summary-row td,
    tr.mg-row td,
    tr.mention-row td,
    tr.rang-row td,
    tr.moy-classe-row td,
    tr.absence-row td      { background: #fff !important; color: #000 !important; }

    /* Name area */
    .name-bar              { display: flex !important; justify-content: space-between !important; align-items: center !important; width: 100% !important; flex-wrap: nowrap !important; }
    .name-badge            { background: none !important; color: #000 !important; border: none !important; display: block !important; padding: 2px 0 !important; flex: 1 !important; }
    .class-badge           { background: none !important; color: #000 !important; border: none !important; padding: 2px 0 !important; white-space: nowrap !important; margin-left: auto !important; text-align: right !important; }
}

/* ══════════════════════════════════════════════════════════════
   SHARED  (applies to both screen and print)
   ══════════════════════════════════════════════════════════════ */
*, *::before, *::after { box-sizing: border-box; }

body, td, th {
    font-family: "Times New Roman", Times, serif;
    font-size: 12px;
    color: #2c2c2c;
}

/* ══════════════════════════════════════════════════════════════
   SCREEN — professional polish
   ══════════════════════════════════════════════════════════════ */
@media screen {
    body { margin: 0; background: #f0ede8; }

    /* ── Page header band ─────────────────────────────────────── */
    .page-header {
        background: #1a2942;
        color: #fff;
        padding: 16px 32px 12px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        border-bottom: 4px solid #c9a84c;
        font-family: 'Source Sans 3', sans-serif;
    }
    .page-header .ph-title {
        font-family: 'Playfair Display', serif;
        font-size: 1.3rem;
        font-weight: 700;
        margin: 0;
    }
    .page-header .ph-sub {
        font-size: .75rem;
        opacity: .6;
        margin-top: 2px;
    }

    /* ── Filter card ──────────────────────────────────────────── */
    .filter-wrap {
        max-width: 760px;
        margin: 26px auto 0;
        padding: 0 18px;
    }
    .filter-card {
        background: #fff;
        border-radius: 8px;
        box-shadow: 0 2px 12px rgba(0,0,0,.08);
        padding: 20px 26px;
        border-top: 3px solid #c9a84c;
    }
    .filter-card h2 {
        font-family: 'Playfair Display', serif;
        font-size: 1rem;
        color: #1a2942;
        margin: 0 0 16px;
        font-weight: 700;
    }
    .filter-row {
        display: flex;
        gap: 14px;
        flex-wrap: wrap;
        align-items: flex-end;
    }
    .filter-group {
        display: flex;
        flex-direction: column;
        gap: 4px;
        flex: 1;
        min-width: 180px;
        font-family: 'Source Sans 3', sans-serif;
    }
    .filter-group label {
        font-size: .72rem;
        font-weight: 600;
        color: #1a2942;
        text-transform: uppercase;
        letter-spacing: .06em;
    }
    .filter-group select {
        border: 1.5px solid #d0cfc9;
        border-radius: 5px;
        padding: 9px 11px;
        font-size: .92rem;
        color: #2c2c2c;
        background: #fafaf8;
        outline: none;
        transition: border-color .2s;
        cursor: pointer;
        font-family: 'Source Sans 3', sans-serif;
    }
    .filter-group select:focus { border-color: #1a2942; }
    .btn-submit {
        background: #1a2942;
        color: #fff;
        border: none;
        padding: 10px 24px;
        border-radius: 5px;
        font-family: 'Source Sans 3', sans-serif;
        font-size: .92rem;
        font-weight: 600;
        cursor: pointer;
        white-space: nowrap;
        transition: background .2s;
    }
    .btn-submit:hover { background: #243a5e; }

    /* ── Toolbar (print + rang toggle) ───────────────────────── */
    .toolbar {
        max-width: 760px;
        margin: 14px auto 4px;
        padding: 0 18px;
        display: flex;
        gap: 10px;
        align-items: center;
        flex-wrap: wrap;
        font-family: 'Source Sans 3', sans-serif;
    }
    .btn-print {
        background: #1a2942;
        color: #fff;
        border: none;
        padding: 8px 18px;
        border-radius: 5px;
        font-size: .84rem;
        cursor: pointer;
        display: flex;
        align-items: center;
        gap: 6px;
        font-family: inherit;
        transition: background .2s;
    }
    .btn-print:hover { background: #243a5e; }
    .btn-rang {
        background: #fff;
        color: #1a2942;
        border: 1.5px solid #c9a84c;
        padding: 8px 18px;
        border-radius: 5px;
        font-size: .84rem;
        cursor: pointer;
        font-family: inherit;
        font-weight: 600;
        transition: background .2s, color .2s;
        display: flex;
        align-items: center;
        gap: 6px;
    }
    .btn-rang:hover     { background: #f5ecd0; }
    .btn-rang.active    { background: #c9a84c; border-color: #c9a84c; color: #1a2942; }
    .rang-info {
        font-size: .78rem;
        color: #888;
        font-family: 'Source Sans 3', sans-serif;
        margin-left: 4px;
    }

    /* ── Bulletin wrap ────────────────────────────────────────── */
    .bulletin-wrap {
        max-width: 980px;
        margin: 20px auto 50px;
        padding: 0 18px;
    }
    .bulletin-card {
        background: #fff;
        border-radius: 8px;
        box-shadow: 0 3px 18px rgba(0,0,0,.09);
        margin-bottom: 32px;
        padding: 18px 20px 20px;
        overflow: hidden;
        border-top: 3px solid #1a2942;
    }

    /* ── Student name header ──────────────────────────────────── */
    .name-bar {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 10px;
        flex-wrap: nowrap;
        gap: 8px;
        width: 100%;
    }
    .name-badge {
        background: none;
        color: #2c2c2c;
        border-radius: 0;
        padding: 4px 0;
        font-size: 13px;
        font-family: 'Times New Roman', serif;
        display: inline-block;
        flex: 1;
    }
    .class-badge {
        background: none;
        color: #2c2c2c;
        border-radius: 0;
        padding: 4px 0;
        font-weight: 700;
        font-size: 13px;
        font-family: 'Times New Roman', serif;
        letter-spacing: .04em;
        white-space: nowrap;
        margin-left: auto;
        text-align: right;
    }

    /* ── Grades table ─────────────────────────────────────────── */
    .bul-table {
        width: 100%;
        border-collapse: collapse;
        font-size: 12px;
        font-family: "Times New Roman", Times, serif;
    }
    .bul-table td, .bul-table th {
        border: 1px solid #c8c4bb;
        padding: 5px 7px;
        vertical-align: middle;
    }
    /* Header row */
    tr.head-row th {
        background: #1a2942;
        color: #fff;
        text-align: center;
        font-weight: 700;
        font-size: 11px;
        letter-spacing: .03em;
        text-transform: uppercase;
        border-color: #1a2942;
    }
    tr.head-row th:first-child { text-align: left; padding-left: 10px; }

    /* Subject (matière) header */
    tr.mat-header td {
        background: #eaeff8;
        color: #1a2942;
        font-weight: 700;
        text-align: center;
        text-transform: uppercase;
        font-size: 11px;
        letter-spacing: .04em;
        border-color: #bfcce8;
    }

    /* Sub-subject rows */
    .bul-table tbody tr:not(.mat-header):not(.total-row):not(.summary-row):not(.mg-row):not(.mention-row):not(.rang-row):not(.moy-classe-row):not(.absence-row):hover {
        background: #f5f3ef;
    }

    /* Total row */
    tr.total-row td {
        background: #f3f1eb;
        font-weight: 700;
        border-top: 2px solid #c8c4bb;
    }

    /* Summary: Total Général */
    tr.summary-row td {
        background: #f7f5f0;
        border-top: 2px solid #b0a890;
    }
    tr.summary-row td:first-child { font-weight: 700; }

    /* Moyenne Générale */
    tr.mg-row td {
        background: #edf5ec;
        border-top: 1px solid #a8d0a4;
    }
    tr.mg-row td:first-child { font-weight: 700; }

    /* Moyenne par matière / 20 */
    tr.moy-mat-row td {
        background: #eef3fb;
        border-top: 1px solid #bfcce8;
    }
    tr.moy-mat-row td:first-child { font-weight: 700; }

    /* Mention — hidden until toggled */
    tr.mention-row           { display: none; }
    tr.mention-row.visible   { display: table-row; }
    tr.mention-row td {
        background: #f4f0e8;
    }
    tr.mention-row td:first-child { font-weight: 700; }

    /* Rang — hidden until toggled */
    tr.rang-row           { display: none; }
    tr.rang-row.visible   { display: table-row; }
    tr.rang-row td {
        background: #eef1ff;
        color: #1a2942;
        font-weight: 700;
        border-top: 1px solid #c0c8f0;
    }

    /* Moyenne de la classe — hidden until toggled */
    tr.moy-classe-row           { display: none; }
    tr.moy-classe-row.visible   { display: table-row; }
    tr.moy-classe-row td {
        background: #f0f7ee;
        color: #1a4a2a;
        font-weight: 700;
        border-top: 1px solid #a8d8a0;
    }

    /* Absence */
    tr.absence-row td { background: #fff8f2; }
    tr.absence-row td:first-child { font-weight: 700; }

    /* ── Grade colour coding ──────────────────────────────────── */
    .g-high { color: #1a7a4a; font-weight: 700; }
    .g-mid  { color: #c07a00; font-weight: 600; }
    .g-low  { color: #b83232; font-weight: 600; }

    /* Mention badges */
    .mention-badge {
        display: inline-block;
        padding: 1px 6px;
        border-radius: 3px;
        font-size: 11px;
        font-weight: 700;
    }
    .mention-EXC { background: #d4f0e4; color: #0f5c32; }
    .mention-TB  { background: #ddeeff; color: #1a4a7a; }
    .mention-B   { background: #e8f8e8; color: #1a5a2a; }
    .mention-AB  { background: #fff3d4; color: #7a4a00; }
    .mention-P   { background: #fff0e0; color: #8a4000; }
    .mention-F   { background: #fde8e8; color: #8a0000; }

    /* ── Observation table ────────────────────────────────────── */
    .obs-table {
        width: 100%;
        border-collapse: collapse;
        margin-top: 10px;
        font-family: "Times New Roman", Times, serif;
    }
    .obs-table td {
        border: 1px solid #c8c4bb;
        padding: 10px 12px;
        vertical-align: top;
    }
    .obs-table .obs-direction { width: 50%; min-height: 80px; }
    .obs-table .obs-text      { width: 100%; min-height: 100px; font-size: 13px; }
    .obs-table .obs-sign      { width: 50%; min-height: 80px; }
}
</style>
</head>
<body>

<?php
error_reporting(E_ALL & ~E_WARNING & ~E_DEPRECATED);
ini_set('log_errors', '0');

/* ── Mention helper ─────────────────────────────────────────────────── */
function mention_label($totlagen, $moycoef) {
    if ($moycoef == 0) return '';
    $moy = round($totlagen * 20 / $moycoef, 1);
    if      ($moy >= 18) return 'EXC.';
    elseif  ($moy >= 16) return 'T.B.';
    elseif  ($moy >= 14) return 'B.';
    elseif  ($moy >= 12) return 'A.B.';
    elseif  ($moy >= 10) return 'P.';
    elseif  ($moy >  0)  return 'F.';
    else                 return '';
}

/* ── Mention with colour badge ──────────────────────────────────────── */
function mention_badge($totlagen, $moycoef) {
    $m = mention_label($totlagen, $moycoef);
    if ($m === '') return '';
    $key = str_replace(['.', ' '], ['', ''], $m);
    // Map label key → CSS class key
    $map = ['EXC' => 'EXC', 'TB' => 'TB', 'B' => 'B', 'AB' => 'AB', 'P' => 'P', 'F' => 'F'];
    $cls = isset($map[$key]) ? 'mention-' . $map[$key] : '';
    return '<span class="mention-badge ' . $cls . '">' . $m . '</span>';
}

/* ── Grade colour span ──────────────────────────────────────────────── */
function g($v) {
    if ($v === null || $v === '') return '';
    if ($v === 'Abs.')            return '<em style="color:#888;font-style:normal">Abs.</em>';
    $n = (float)$v;
    if ($n >= 14) return '<span class="g-high">' . $v . '</span>';
    if ($n >= 10) return '<span class="g-mid">'  . $v . '</span>';
    return              '<span class="g-low">'   . $v . '</span>';
}

/* ── Page header band ────────────────────────────────────────────────── */
echo '<div class="noprint page-header">';
echo  '<div>';
echo    '<div class="ph-title">Bulletin de Notes</div>';
echo    '<div class="ph-sub">Tableau de bord académique</div>';
echo  '</div>';
echo '</div>';

echo '<div class="noprint">';
include 'header.php';
echo '</div>';

$cycle = intval($_POST['cycle'] ?? $_GET['cycle'] ?? 0);
include '_serveur.php';
mysqli_set_charset($link, 'utf8mb4');

/* ── Academic year selector ───────────────────────────────────────────
   'actuelle'  → current year: students / grades
   '24-25'     → archived year: students25 / grades25
   Whitelisted on purpose since these values are interpolated directly
   into table names below — never trust raw user input for identifiers. */
$annee = $_POST['annee'] ?? $_GET['annee'] ?? 'actuelle';
if (!in_array($annee, ['actuelle', '24-25'], true)) $annee = 'actuelle';

if ($annee === '24-25') {
    $tbl_students = 'students25';
    $tbl_grades   = 'grades25';
} else {
    $tbl_students = 'students';
    $tbl_grades   = 'grades';
}
?>

<form method="post" action="" id="main-form">
<input name="cycle" type="hidden" value="<?php echo $cycle; ?>">

<?php
/* ── Class dropdown ─────────────────────────────────────────────────── */
$sql = 'SELECT id, name FROM classes
        WHERE cycleID="' . mysqli_real_escape_string($link, $cycle) . '"
        ORDER BY id ASC';
$req = mysqli_query($link, $sql);

echo '<div class="noprint filter-wrap">';
echo  '<div class="filter-card">';
echo    '<h2>Sélection de la classe</h2>';
echo    '<div class="filter-row">';
echo      '<div class="filter-group">';
echo        '<label for="sel_cla">Classe</label>';
echo        '<select name="cla" id="sel_cla">';
while ($data = mysqli_fetch_assoc($req)) {
    $sel = (isset($_POST['cla']) && $_POST['cla'] == $data['id']) ? ' selected' : '';
    echo '<option value="' . intval($data['id']) . '"' . $sel . '>'
       . htmlspecialchars(mb_strtoupper($data['name'], 'UTF-8'))
       . '</option>';
}
echo        '</select>';
echo      '</div>';
echo      '<div class="filter-group">';
echo        '<label for="sel_annee">Année scolaire</label>';
echo        '<select name="annee" id="sel_annee">';
echo          '<option value="actuelle"' . ($annee === 'actuelle' ? ' selected' : '') . '>2025-2026 (actuelle)</option>';
echo          '<option value="24-25"'    . ($annee === '24-25'    ? ' selected' : '') . '>2024-2025 (archivée)</option>';
echo        '</select>';
echo      '</div>';
echo      '<input name="chercher" type="submit" value="Afficher les bulletins" class="btn-submit" />';
echo    '</div>';
echo  '</div>';
echo '</div>';
echo '</form>';

if (!isset($_POST['chercher'])) exit;

/* ════════════════════════════════════════════════════════════════════════
   MAIN PROCESSING
   ════════════════════════════════════════════════════════════════════════ */
$classeid1 = intval($_POST['cla']);

/* ── Delete old moyens (current year only — this table isn't year-specific,
     so we must not let an archived-year view overwrite it) ────────────── */
if ($annee === 'actuelle') {
    mysqli_query($link, 'DELETE FROM moyens WHERE classID=' . $classeid1);
}

/* ── Semesters / contrôles ──────────────────────────────────────────── */
$sql_sem = 'SELECT s.id, s.name
            FROM semesters s
            INNER JOIN classesSemesters cs ON cs.semesterID = s.id
            WHERE cs.classID = ' . $classeid1 . '
            ORDER BY s.id ASC';
$res_sem = mysqli_query($link, $sql_sem);

$ctrls = [];
if ($res_sem) {
    while ($r = mysqli_fetch_assoc($res_sem)) {
        $ctrls[(int)$r['id']] = $r['name'];
    }
}
if (empty($ctrls)) {
    echo "<p style='color:red;padding:20px'>Aucun semestre trouvé pour cette classe.</p>";
    exit;
}

$ctrl_ids  = array_keys($ctrls);
$nb_ctrls  = count($ctrl_ids);
$col_width = round(52 / ($nb_ctrls + 1), 1);

/* ── Sub-subjects & coefficients ────────────────────────────────────── */
$sql = 'SELECT
            gs.coeficient   AS coef,
            gs.subSubjectID AS subSubjectID,
            ss.subjectID    AS subjectID,
            ss.name         AS sousmat_name,
            su.id           AS matID,
            su.name         AS mat_name
        FROM gradesSubjects gs
        INNER JOIN subSubjects ss ON gs.subSubjectID = ss.id
        INNER JOIN subjects    su ON ss.subjectID    = su.id
        WHERE gs.classID = ' . $classeid1 . '
        ORDER BY su.ordering ASC, gs.ordering ASC';
$req = mysqli_query($link, $sql);
if (!$req) { echo 'ERREUR matières: ' . mysqli_error($link); exit; }

$coef_arr = $sousmatid_arr = $matsous_arr = $sousmat_arr = $matid_arr = $mat_arr = [];
$i = 0;
while ($data = mysqli_fetch_assoc($req)) {
    $coef_arr[$i]      = $data['coef'];
    $sousmatid_arr[$i] = $data['subSubjectID'];
    $matsous_arr[$i]   = $data['subjectID'];
    $sousmat_arr[$i]   = $data['sousmat_name'];
    $matid_arr[$i]     = $data['matID'];
    $mat_arr[$i]       = $data['mat_name'];
    $i++;
}
$mat2   = array_unique($mat_arr,   SORT_REGULAR);
$matid2 = array_unique($matid_arr, SORT_REGULAR);

/* ── Students list ──────────────────────────────────────────────────── */
$sql_stu = 'SELECT
                st.id        AS studentid,
                st.firstName AS prenom,
                st.lastName  AS famille,
                us.firstName AS pere,
                cl.name      AS cl
            FROM ' . $tbl_students . ' st
            INNER JOIN classes cl ON cl.id = st.classID
            LEFT JOIN  users   us ON us.id = st.userID
            WHERE st.classID = ' . $classeid1 . '
            ORDER BY st.firstName, st.lastName, us.firstName';
$res_stu = mysqli_query($link, $sql_stu);
if (!$res_stu) { echo 'ERREUR élèves: ' . mysqli_error($link); exit; }

$students = [];
while ($row = mysqli_fetch_assoc($res_stu)) {
    $students[] = $row;
}
if (empty($students)) {
    echo "<p style='color:red;padding:20px'>Classe vide ou sans élèves.</p>";
    exit;
}

/* ── Grade index: [studentID][subSubjectID][semesterID] ─────────────── */
$sql_gr = 'SELECT
               gr.studentID    AS studentid,
               gr.subSubjectID AS discipid,
               gr.semesterID   AS ctrlid,
               gr.grade        AS grade,
               gs.coeficient   AS discipcoef
           FROM ' . $tbl_grades . ' gr
           LEFT JOIN gradesSubjects gs
               ON gs.subSubjectID = gr.subSubjectID
              AND gs.classID      = gr.classID
           WHERE gr.classID = ' . $classeid1 . '
           ORDER BY gr.studentID, gr.subSubjectID, gr.semesterID';
$res_gr = mysqli_query($link, $sql_gr);
if (!$res_gr) { echo 'ERREUR notes: ' . mysqli_error($link); exit; }

$grades_index = [];
while ($row = mysqli_fetch_assoc($res_gr)) {
    $grades_index[(int)$row['studentid']]
                 [(int)$row['discipid']]
                 [(int)$row['ctrlid']] = [
        'grade' => $row['grade'],
        'coef'  => (float)$row['discipcoef'],
    ];
}

/* ── Save totals into moyens (studentID, classID, semesterID, subjectID, total, coef) ──
     Same guard as above: only touch this shared table for the current year. */
if ($annee === 'actuelle') {
foreach ($students as $stu) {
    $sid = intval($stu['studentid']);
    foreach ($ctrl_ids as $cid) {
        // Loop over each unique subject
        foreach ($matid2 as $s => $matid_val) {
            $sum_g = 0; $sum_c = 0;
            // Sum all sub-subjects belonging to this subject
            foreach ($sousmatid_arr as $idx => $ssid) {
                if ($matsous_arr[$idx] != $matid_val) continue;
                if (isset($grades_index[$sid][$ssid][$cid])) {
                    $e = $grades_index[$sid][$ssid][$cid];
                    if ($e['grade'] != -1 && $e['grade'] !== null && $e['grade'] !== '') {
                        $sum_g += $e['grade'];
                        $sum_c += $e['coef'];
                    }
                }
            }
            if ($sum_c > 0 && $sum_g > 0) {
                mysqli_query($link,
                    'INSERT INTO moyens (studentID, classID, semesterID, subjectID, total, coef) VALUES('
                    . intval($sid)      . ','
                    . intval($classeid1). ','
                    . intval($cid)      . ','
                    . intval($matid_val). ','
                    . floatval($sum_g)  . ','
                    . intval($sum_c)    . ')'
                );
            }
        }
    }
}
} // end if ($annee === 'actuelle') — moyens write guard

/* ════════════════════════════════════════════════════════════════════════
   PRE-PASS — per-month (per-contrôle) moyenne and rank
   ════════════════════════════════════════════════════════════════════════ */

/* $stu_moy[$sid][$cid] = MG /20 for that student/month, null = no grades */
$stu_moy = [];
foreach ($students as $stu) {
    $sid = intval($stu['studentid']);
    foreach ($ctrl_ids as $cid) {
        $tl = 0; $mc = 0;
        foreach ($sousmatid_arr as $idx => $ssid) {
            if (isset($grades_index[$sid][$ssid][$cid])) {
                $e = $grades_index[$sid][$ssid][$cid];
                if ($e['grade'] != -1 && $e['grade'] !== null && $e['grade'] !== '') {
                    $tl += $e['grade'];
                    $mc += $e['coef'];
                }
            }
        }
        $stu_moy[$sid][$cid] = ($mc > 0) ? round($tl * 20 / $mc, 2) : null;
    }
}

/* $classe_moy_ctrl[$cid] = class average for that month
   denominator = students who actually have at least one real grade */
$classe_moy_ctrl = [];
foreach ($ctrl_ids as $cid) {
    $sum = 0; $cnt = 0;
    foreach ($students as $stu) {
        $sid = intval($stu['studentid']);
        if ($stu_moy[$sid][$cid] !== null) {
            $sum += $stu_moy[$sid][$cid];
            $cnt++;
        }
    }
    $classe_moy_ctrl[$cid] = ($cnt > 0) ? round($sum / $cnt, 2) : null;
}

/* $rang[$sid][$cid]   = rank (1 = best) among graded students, null if absent
   $rang_total[$cid]   = number of students with grades (the denominator)     */
$rang       = [];
$rang_total = [];
foreach ($ctrl_ids as $cid) {
    $moys = [];
    foreach ($students as $stu) {
        $sid = intval($stu['studentid']);
        if ($stu_moy[$sid][$cid] !== null) {
            $moys[$sid] = $stu_moy[$sid][$cid];
        }
    }
    arsort($moys);
    $rang_total[$cid] = count($moys);
    $i = 0; $prev_val = null; $prev_pos = 1;
    foreach ($moys as $sid => $val) {
        $i++;
        $rang[$sid][$cid] = ($prev_val !== null && $val == $prev_val) ? $prev_pos : $i;
        $prev_pos = $rang[$sid][$cid];
        $prev_val = $val;
    }
    // students without grades → null
    foreach ($students as $stu) {
        $sid = intval($stu['studentid']);
        if (!isset($rang[$sid][$cid])) $rang[$sid][$cid] = null;
    }
}

/* ── Toolbar ────────────────────────────────────────────────────────── */
echo '<div class="noprint toolbar">';
echo  '<button type="button" class="btn-print" onclick="window.print()">';
echo    '<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">';
echo      '<path d="M6 9V2h12v7"/><rect x="6" y="17" width="12" height="5"/>';
echo      '<path d="M6 13H4a2 2 0 0 0-2 2v4h4"/><path d="M18 13h2a2 2 0 0 1 2 2v4h-4"/>';
echo    '</svg>';
echo    ' Imprimer';
echo  '</button>';
echo  '<button type="button" class="btn-rang" id="rang-btn" onclick="toggleRang()">';
echo    '☰ Afficher le Rang';
echo  '</button>';
echo  '<button type="button" class="btn-rang" id="moy-btn" onclick="toggleMoyClasse()">';
echo    '☰ Afficher Moy. Classe';
echo  '</button>';
echo  '<button type="button" class="btn-rang" id="mention-btn" onclick="toggleMention()">';
echo    '☰ Afficher la Mention';
echo  '</button>';
echo  '<span class="rang-info">Ces lignes s\'affichent aussi à l\'impression si activées</span>';
if ($annee !== 'actuelle') {
    echo '<span class="rang-info" style="color:#b83232;font-weight:700">📁 Année archivée : 2024-2025</span>';
}
echo '</div>';

/* ════════════════════════════════════════════════════════════════════════
   DISPLAY — one bulletin per student
   ════════════════════════════════════════════════════════════════════════ */
echo '<div class="bulletin-wrap">';

foreach ($students as $stu) {

    $sid_cur = intval($stu['studentid']);

    echo '<div class="page-break bulletin-card">';

    /* ── School header (titre.php) ─────────────────────────────────── */
    include 'titre.php';

    /* ── Student name bar ──────────────────────────────────────────── */
    echo '<div class="name-bar">';
    echo  '<span class="name-badge">';
    echo    'Nom de l\'élève :&nbsp;<b>';
    echo     mb_strtoupper(htmlspecialchars($stu['prenom']), 'UTF-8')  . '&nbsp;&nbsp;';
    echo     mb_strtoupper(htmlspecialchars($stu['pere']), 'UTF-8')    . '&nbsp;&nbsp;';
    echo     mb_strtoupper(htmlspecialchars($stu['famille']), 'UTF-8');
    echo    '</b>';
    echo  '</span>';
    echo  '<span class="class-badge">Classe : ' . mb_strtoupper(htmlspecialchars($stu['cl']), 'UTF-8')
        . ($annee !== 'actuelle' ? ' — 2024-2025' : '') . '</span>';
    echo '</div>';

    /* ── Grades table ──────────────────────────────────────────────── */
    echo '<table class="bul-table" width="98%" border="1" align="center" cellspacing="0">';

    // ─ Header row ─
    echo '<thead>';
    echo '<tr class="head-row">';
    echo  '<th width="40%" style="text-align:left;padding-left:10px">Matières</th>';
    echo  '<th width="8%" align="center">Coef.</th>';
    foreach ($ctrls as $cid => $sname) {
        echo '<th width="' . $col_width . '%" align="center">' . htmlspecialchars($sname) . '</th>';
    }
    echo  '<th width="' . $col_width . '%" align="center">M.G.</th>';
    echo '</tr>';
    echo '</thead>';
    echo '<tbody>';

    $totlagen = array_fill_keys($ctrl_ids, 0);
    $moycoef  = array_fill_keys($ctrl_ids, 0);
    $coeftot  = 0;
    $sou      = 0;

    /* ── Subjects loop ─────────────────────────────────────────────── */
    foreach ($mat2 as $s => $nom_mat) {

        if (empty($nom_mat)) {
            while (isset($matsous_arr[$sou]) && $matsous_arr[$sou] == $matid2[$s]) {
                $sou++;
            }
            continue;
        }

        $discpsum         = array_fill_keys($ctrl_ids, 0);
        $matcoef_par_ctrl = array_fill_keys($ctrl_ids, 0);
        $coefmat_current  = 0;
        $sum_sousmg       = 0;

        // Subject header
        echo '<tr class="mat-header">';
        echo  '<td width="40%" align="center">';
        echo    '<b>' . mb_strtoupper(htmlspecialchars($nom_mat), 'UTF-8') . '</b>';
        echo  '</td>';
        echo  '<td></td>';
        for ($c = 0; $c <= $nb_ctrls; $c++) echo '<td></td>';
        echo '</tr>';

        // ─ Sub-subjects ─
        while (isset($matsous_arr[$sou]) && $matsous_arr[$sou] == $matid2[$s]) {

            $coef             = (int)$coef_arr[$sou];
            $subsubid         = (int)$sousmatid_arr[$sou];
            $coefmat_current += $coef;
            $coeftot         += $coef;

            echo '<tr>';
            echo  '<td>&nbsp;&nbsp;' . htmlspecialchars($sousmat_arr[$sou]) . '</td>';
            echo  '<td align="center"><b>' . $coef . '</b></td>';

            $notes    = array_fill_keys($ctrl_ids, null);
            $sumg     = 0;
            $countgra = 0;

            foreach ($ctrl_ids as $cid) {
                if (isset($grades_index[$sid_cur][$subsubid][$cid])) {
                    $entry = $grades_index[$sid_cur][$subsubid][$cid];
                    $gv    = $entry['grade'];
                    $dc    = $entry['coef'];
                    if ($gv == -1) {
                        $notes[$cid] = 'Abs.';
                    } else {
                        $notes[$cid]             = $gv;
                        $matcoef_par_ctrl[$cid] += $dc;
                        $discpsum[$cid]          += $gv;
                        $sumg += $gv; $countgra++;
                    }
                }
            }

            foreach ($ctrl_ids as $cid) {
                $v = $notes[$cid];
                if ($v === null) echo '<td></td>';
                else             echo '<td align="center">' . g($v) . '</td>';
            }

            $moyg = ($countgra > 0) ? round($sumg / $countgra, 2) : 0;
            echo '<td align="center">' . ($moyg == 0 ? '' : g($moyg)) . '</td>';
            echo '</tr>';

            $sum_sousmg += $moyg;
            $sou++;
        } // end sub-subjects

        // ─ Total row per subject ─
        echo '<tr class="total-row">';
        echo  '<td><b>TOTAL ' . mb_strtoupper(htmlspecialchars($nom_mat), 'UTF-8') . '</b></td>';
        echo  '<td align="center"><b>' . $coefmat_current . '</b></td>';
        $cd = 0; $ds = 0;
        foreach ($ctrl_ids as $cid) {
            if ($discpsum[$cid] != 0) {
                $cd++; $ds += $discpsum[$cid];
                echo '<td align="center"><b>' . $discpsum[$cid] . '</b></td>';
            } else {
                echo '<td></td>';
            }
        }
        if ($cd == 0) $cd = 1;
        echo '<td align="center"><b>' . ($sum_sousmg == 0 ? '' : $sum_sousmg) . '</b></td>';
        echo '</tr>';

        // ─ Moyenne par matière / 20 ─
        echo '<tr class="moy-mat-row">';
        echo  '<td><b>MOYENNE ' . mb_strtoupper(htmlspecialchars($nom_mat), 'UTF-8') . ' </b></td>';
        echo  '<td align="center"><b>20</b></td>';
        $moy_sum = 0; $moy_cnt = 0;
        foreach ($ctrl_ids as $cid) {
            $denom = ($matcoef_par_ctrl[$cid] > 0) ? $matcoef_par_ctrl[$cid]
                   : ($coefmat_current > 0 ? $coefmat_current : 1);
            if ($discpsum[$cid] == 0) {
                echo '<td></td>';
            } else {
                $mv = round($discpsum[$cid] * 20 / $denom, 2);
                echo '<td align="center"><b>' . g($mv) . '</b></td>';
                $moy_sum += $mv; $moy_cnt++;
            }
        }
        if ($moy_cnt == 0) $moy_cnt = 1;
        $moy_mg = round($moy_sum / $moy_cnt, 2);
        echo '<td align="center"><b>' . ($moy_mg == 0 ? '' : g($moy_mg)) . '</b></td>';
        echo '</tr>';

        // Accumulate grand totals
        foreach ($ctrl_ids as $cid) {
            $totlagen[$cid] += $discpsum[$cid];
            $moycoef[$cid]  += $matcoef_par_ctrl[$cid];
        }

    } // end subjects

    /* ── Spacer ────────────────────────────────────────────────────── */
    echo '<tr><td colspan="' . ($nb_ctrls + 3) . '" style="height:8px;border:none"></td></tr>';

    /* ── Total Général ─────────────────────────────────────────────── */
    echo '<tr class="summary-row">';
    echo  '<td><b>Total Général</b></td>';
    echo  '<td align="center"><b>' . $coeftot . '</b></td>';

    $ref_coef = 0;
    foreach ($ctrl_ids as $cid) {
        if ($moycoef[$cid] > 0) { $ref_coef = $moycoef[$cid]; break; }
    }
    $tg_sum = 0; $tg_cnt = 0;
    foreach ($ctrl_ids as $cid) {
        if ($totlagen[$cid] == 0) {
            echo '<td></td>';
        } else {
            echo '<td align="center"><b>' . $totlagen[$cid] . '</b></td>';
            if ($moycoef[$cid] > 0) {
                $tg_sum += $totlagen[$cid] * $ref_coef / $moycoef[$cid];
                $tg_cnt++;
            }
        }
    }
    $tg_mg = ($tg_cnt > 0) ? round($tg_sum / $tg_cnt, 2) : 0;
    echo  '<td align="center"><b>' . ($tg_mg == 0 ? '' : $tg_mg) . '</b></td>';
    echo '</tr>';

    /* ── Moyenne Générale ──────────────────────────────────────────── */
    echo '<tr class="mg-row">';
    echo  '<td><b>Moyenne Générale</b></td>';
    echo  '<td align="center"><b>20</b></td>';
    $sumMoy = 0; $nbMoy = 0;
    foreach ($ctrl_ids as $cid) {
        $mc = ($moycoef[$cid] == 0) ? 1 : $moycoef[$cid];
        if ($totlagen[$cid] == 0) {
            echo '<td></td>';
        } else {
            $mv = round($totlagen[$cid] * 20 / $mc, 2);
            echo '<td align="center"><b>' . g($mv) . '</b></td>';
            $sumMoy += $mv; $nbMoy++;
        }
    }
    if ($nbMoy == 0) $nbMoy = 1;
    $mg_final = round($sumMoy / $nbMoy, 2);
    echo  '<td align="center"><b>' . g($mg_final) . '</b></td>';
    echo '</tr>';

    /* ── Mention ───────────────────────────────────────────────────── */
    echo '<tr class="mention-row">';
    echo  '<td><b>Mention</b></td><td></td>';
    foreach ($ctrl_ids as $cid) {
        $mc = ($moycoef[$cid] == 0) ? 1 : $moycoef[$cid];
        echo '<td align="center">' . mention_badge($totlagen[$cid], $mc) . '</td>';
    }
    echo  '<td></td>';
    echo '</tr>';

    /* ── Moyenne de la Classe (optional — toggled by JS) ──────────────── */
    echo '<tr class="moy-classe-row">';
    echo  '<td><b>Moy. de la Classe</b></td><td></td>';
    foreach ($ctrl_ids as $cid) {
        $cm = $classe_moy_ctrl[$cid];
        echo ($cm !== null)
            ? '<td align="center"><b>' . $cm . '</b></td>'
            : '<td></td>';
    }
    echo  '<td></td>';
    echo '</tr>';

    /* ── Rang (optional — toggled by JS) ───────────────────────────── */
    echo '<tr class="rang-row">';
    echo  '<td><b>Rang</b></td><td></td>';
    foreach ($ctrl_ids as $cid) {
        $r  = $rang[$sid_cur][$cid] ?? null;
        $tot = $rang_total[$cid] ?? 0;
        echo ($r !== null)
            ? '<td align="center"><b>' . $r . '/' . $tot . '</b></td>'
            : '<td></td>';
    }
    echo  '<td></td>';
    echo '</tr>';

    /* ── Absences ──────────────────────────────────────────────────── */
    $req_abs = mysqli_query($link,
        'SELECT * FROM absenceclasse WHERE studentID=' . $sid_cur);
    $abs    = [];
    $studID = null;
    while ($d = mysqli_fetch_array($req_abs)) {
        $studID = (int)$d[1];
        $abs[$studID][(int)$d[5]] = $d[4];
    }
    echo '<tr class="absence-row">';
    echo  '<td><b>Absence</b></td><td></td>';
    foreach ($ctrl_ids as $cid) {
        $v = ($studID == $sid_cur && isset($abs[$studID][$cid]))
           ? $abs[$studID][$cid] : '';
        echo '<td align="center">' . htmlspecialchars((string)$v) . '</td>';
    }
    echo  '<td></td>';
    echo '</tr>';

    echo '</tbody>';
    echo '</table>';

    /* ── Observations + Signatures ─────────────────────────────────── */
    $req_obs = mysqli_query($link,
        'SELECT obser FROM observationsele WHERE studentID=' . $sid_cur);
    $obser = '';
    if ($row = mysqli_fetch_assoc($req_obs)) {
        $obser = $row['obser'];
    }

    echo '<table class="obs-table" width="98%" border="1" align="center" cellspacing="0">';
    echo  '<tr>';
    echo    '<td class="obs-text" colspan="2">';
    echo      '<b>Appréciations</b><br>';
    echo      '<span style="font-weight:normal">' . htmlspecialchars($obser) . '</span>';
    echo      '<br><br><br>';
    echo    '</td>';
    echo  '</tr>';
    echo  '<tr>';
    echo    '<td class="obs-direction"><b>Direction</b><br><br>
	    <span style="font-weight:normal; font-style:italic; font-size:14px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Sr. Carole Arrouk</span>';
    echo      '<br><br><br></td>';
    echo    '<td class="obs-sign"><b>Signature du responsable<br><br><br><br></b></td>';
    echo  '</tr>';
    echo '</table>';

    echo '</div>'; // close .bulletin-card / .page-break

} // end foreach students

echo '</div>'; // close .bulletin-wrap
?>

<script>
/* ── Rang toggle ─────────────────────────────────────────────────────── */
function toggleRang() {
    var rows = document.querySelectorAll('tr.rang-row');
    var btn  = document.getElementById('rang-btn');
    var shown = rows.length > 0 && rows[0].classList.contains('visible');
    rows.forEach(function(r) { r.classList.toggle('visible', !shown); });
    if (!shown) {
        btn.innerHTML = '✕ Masquer le Rang';
        btn.classList.add('active');
    } else {
        btn.innerHTML = '☰ Afficher le Rang';
        btn.classList.remove('active');
    }
}

/* ── Moyenne de la Classe toggle ─────────────────────────────────────── */
function toggleMoyClasse() {
    var rows = document.querySelectorAll('tr.moy-classe-row');
    var btn  = document.getElementById('moy-btn');
    var shown = rows.length > 0 && rows[0].classList.contains('visible');
    rows.forEach(function(r) { r.classList.toggle('visible', !shown); });
    if (!shown) {
        btn.innerHTML = '✕ Masquer Moy. Classe';
        btn.classList.add('active');
    } else {
        btn.innerHTML = '☰ Afficher Moy. Classe';
        btn.classList.remove('active');
    }
}

/* ── Mention toggle ──────────────────────────────────────────────────── */
function toggleMention() {
    var rows = document.querySelectorAll('tr.mention-row');
    var btn  = document.getElementById('mention-btn');
    var shown = rows.length > 0 && rows[0].classList.contains('visible');
    rows.forEach(function(r) { r.classList.toggle('visible', !shown); });
    if (!shown) {
        btn.innerHTML = '✕ Masquer la Mention';
        btn.classList.add('active');
    } else {
        btn.innerHTML = '☰ Afficher la Mention';
        btn.classList.remove('active');
    }
}
</script>

</body>
</html>
