<?php declare(strict_types=1);
/* ============================================================================
 * Assessments & Projects — Admin (Course first, dynamic Modules & Students)
 * ========================================================================== */
ini_set('display_errors', 1);
error_reporting(E_ALL);

define('APP_ROOT', dirname(__DIR__, 2)); // .../elms

/* --- bootstrap / guards --- */
if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

$PAGE_TITLE = 'Assessments & Projects';
$ACTIVE = 'assessments';

require_once APP_ROOT . '/includes/admin_auth.php';
require_once APP_ROOT . '/includes/db.php';

/* --- CSRF --- */
function csrf_token(): string { if (empty($_SESSION['csrf'])) $_SESSION['csrf']=bin2hex(random_bytes(16)); return $_SESSION['csrf']; }
function require_csrf(): void {
  if (!isset($_POST['csrf']) || !hash_equals($_SESSION['csrf'] ?? '', (string)$_POST['csrf'])) {
    http_response_code(403); exit('CSRF validation failed');
  }
}

/* --- helpers --- */
if (!function_exists('esc')) {
  function esc($s){
    return htmlspecialchars((string)$s, ENT_QUOTES|ENT_SUBSTITUTE,'UTF-8');
  }
}
function base_url(): string {
  $dir = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/'); $dir = preg_replace('#/admin/assessments$#','',$dir);
  return $dir === '' ? '/' : $dir;
}
function url_for(string $path): string { if ($path===''||$path[0]!=='/') $path='/'.$path; return rtrim(base_url(),'/').$path; }
function dt_or_null(?string $in): ?string { $in=trim((string)$in); if($in==='') return null; $in=str_replace('T',' ',$in); $ts=strtotime($in); return $ts?date('Y-m-d H:i:s',$ts):null; }
function dt_to_input(?string $db): string { return $db?str_replace(' ','T',substr($db,0,16)) : ''; }
function short_text(?string $s,int $n=90): string {
  $s=(string)($s??''); if($s==='') return ''; $len=function_exists('mb_strlen')?mb_strlen($s,'UTF-8'):strlen($s);
  return $len>$n ? ((function_exists('mb_substr')?mb_substr($s,0,$n,'UTF-8'):substr($s,0,$n)).'…') : $s;
}

/* --- schema helpers --- */
function table_exists(mysqli $db,string $t):bool{
  $t=$db->real_escape_string($t);
  $q=$db->query("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='$t' LIMIT 1");
  return (bool)($q && $q->num_rows);
}
function col_exists(mysqli $db,string $t,string $c):bool{
  $t=$db->real_escape_string($t); $c=$db->real_escape_string($c);
  $q=$db->query("SHOW COLUMNS FROM `$t` LIKE '$c'"); return (bool)($q && $q->num_rows);
}
function idx_exists(mysqli $db,string $t,string $i):bool{
  $t=$db->real_escape_string($t); $i=$db->real_escape_string($i);
  $q=$db->query("SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='$t' AND INDEX_NAME='$i' LIMIT 1");
  return (bool)($q && $q->num_rows);
}

/* --- ensure schema (safe adds) --- */
function ensure_schema(mysqli $db): void {
  if (!table_exists($db,'lms_assessments')) {
    $db->query("CREATE TABLE lms_assessments(
      id INT AUTO_INCREMENT PRIMARY KEY,
      title VARCHAR(255) NOT NULL,
      description TEXT NULL,
      type ENUM('assignment','project') NOT NULL DEFAULT 'assignment',
      course_id INT NULL,
      module_id INT NULL,
      available_from DATETIME NULL,
      available_to   DATETIME NULL,
      due_at         DATETIME NULL,
      release_at     DATETIME NULL,
      max_score INT NOT NULL DEFAULT 100,
      active TINYINT(1) NOT NULL DEFAULT 1,
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
  } else {
    if (!col_exists($db,'lms_assessments','description'))   $db->query("ALTER TABLE lms_assessments ADD description TEXT NULL AFTER title");
    if (!col_exists($db,'lms_assessments','type'))          $db->query("ALTER TABLE lms_assessments ADD type ENUM('assignment','project') NOT NULL DEFAULT 'assignment'");
    if (!col_exists($db,'lms_assessments','course_id'))     $db->query("ALTER TABLE lms_assessments ADD course_id INT NULL");
    if (!col_exists($db,'lms_assessments','module_id'))     $db->query("ALTER TABLE lms_assessments ADD module_id INT NULL");
    if (!col_exists($db,'lms_assessments','available_from'))$db->query("ALTER TABLE lms_assessments ADD available_from DATETIME NULL");
    if (!col_exists($db,'lms_assessments','available_to'))  $db->query("ALTER TABLE lms_assessments ADD available_to   DATETIME NULL");
    if (!col_exists($db,'lms_assessments','due_at'))        $db->query("ALTER TABLE lms_assessments ADD due_at         DATETIME NULL");
    if (!col_exists($db,'lms_assessments','release_at'))    $db->query("ALTER TABLE lms_assessments ADD release_at     DATETIME NULL");
    if (!col_exists($db,'lms_assessments','max_score'))     $db->query("ALTER TABLE lms_assessments ADD max_score      INT NOT NULL DEFAULT 100");
    if (!col_exists($db,'lms_assessments','active'))        $db->query("ALTER TABLE lms_assessments ADD active         TINYINT(1) NOT NULL DEFAULT 1");
  }
  if (!table_exists($db,'lms_assessment_batches'))  $db->query("CREATE TABLE lms_assessment_batches(assessment_id INT NOT NULL, batch_id INT NOT NULL, PRIMARY KEY(assessment_id,batch_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
  if (!table_exists($db,'lms_assessment_students')) $db->query("CREATE TABLE lms_assessment_students(assessment_id INT NOT NULL, student_id INT NOT NULL, PRIMARY KEY(assessment_id,student_id)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
  if (!idx_exists($db,'lms_assessments','idx_ass_course')) $db->query("CREATE INDEX idx_ass_course ON lms_assessments(course_id)");
  if (!idx_exists($db,'lms_assessments','idx_ass_active')) $db->query("CREATE INDEX idx_ass_active ON lms_assessments(active)");

  $db->query("CREATE TABLE IF NOT EXISTS lms_assessment_attachments(
    id INT AUTO_INCREMENT PRIMARY KEY,
    assessment_id INT NOT NULL,
    file_path VARCHAR(255) NOT NULL,
    uploaded_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    INDEX(assessment_id)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
}
ensure_schema($mysqli);

/* --- dynamic label helper --- */
function label_col(mysqli $db,string $table,array $candidates): string {
  $cols=[]; if ($res=$db->query("SHOW COLUMNS FROM `$table`")) while($r=$res->fetch_assoc()) $cols[]=$r['Field'];
  foreach($candidates as $c) if (in_array($c,$cols,true)) return $c; return 'id';
}

/* --- attachments helpers --- */
function save_assessment_attachment(mysqli $db, int $assessment_id, array $file): ?string {
  if (empty($file['name']) || !is_uploaded_file($file['tmp_name'])) return null;
  $dir = realpath(APP_ROOT).'/uploads/assessments'; if (!is_dir($dir)) @mkdir($dir,0775,true);
  $ext=strtolower(pathinfo($file['name'],PATHINFO_EXTENSION));
  $base=preg_replace('/[^A-Za-z0-9._-]+/','_', pathinfo($file['name'],PATHINFO_FILENAME));
  $name=date('Ymd_His')."_ass{$assessment_id}_{$base}".($ext?".$ext":''); $dest=$dir.'/'.$name;
  if(!move_uploaded_file($file['tmp_name'],$dest)) return null;
  $public='/uploads/assessments/'.$name;
  $st=$db->prepare("INSERT INTO lms_assessment_attachments(assessment_id,file_path) VALUES(?,?)"); $st->bind_param('is',$assessment_id,$public); $st->execute(); $st->close();
  return $public;
}
function get_latest_attachment(mysqli $db, int $assessment_id): ?string {
  $st=$db->prepare("SELECT file_path FROM lms_assessment_attachments WHERE assessment_id=? ORDER BY id DESC LIMIT 1");
  $st->bind_param('i',$assessment_id); $st->execute(); $st->bind_result($p); $ok=$st->fetch(); $st->close(); return $ok?$p:null;
}

/* --- data sources --- */
function courses_list(mysqli $db): array {
  $col=label_col($db,'courses',['course_name','name','title','label']);
  $rs=$db->query("SELECT id, COALESCE($col,'#') AS label FROM courses ORDER BY id DESC"); $out=[];
  while($r=$rs->fetch_assoc()) $out[(int)$r['id']]=$r['label']; return $out;
}
function course_modules_list(mysqli $db, ?int $courseId=null): array {
  if (!$db->query("SHOW TABLES LIKE 'course_modules'")->num_rows) return [];
  if ($courseId){ $st=$db->prepare("SELECT id,title FROM course_modules WHERE course_id=? ORDER BY sort_order ASC, id ASC"); $st->bind_param('i',$courseId); $st->execute(); $rs=$st->get_result(); }
  else { $rs=$db->query("SELECT id,title FROM course_modules ORDER BY sort_order ASC, id ASC"); }
  $out=[]; while($r=$rs->fetch_assoc()) $out[(int)$r['id']]=$r['title']; if(isset($st)) $st->close(); return $out;
}
function batches_list(mysqli $db, ?int $courseId=null): array {
  if (!$db->query("SHOW TABLES LIKE 'batches'")->num_rows) return [];
  $nm=label_col($db,'batches',['batch_name','name','title','label']);
  if ($courseId){ $st=$db->prepare("SELECT id,COALESCE($nm,'#') AS label FROM batches WHERE course_id=? ORDER BY id DESC"); $st->bind_param('i',$courseId); $st->execute(); $rs=$st->get_result(); }
  else { $rs=$db->query("SELECT id,COALESCE($nm,'#') AS label FROM batches ORDER BY id DESC"); }
  $out=[]; while($r=$rs->fetch_assoc()) $out[(int)$r['id']]=$r['label']; if(isset($st)) $st->close(); return $out;
}

function tbl_exists_ass(mysqli $db, string $table): bool {
    return table_exists($db, $table);
}

function first_existing_ass(mysqli $db, string $table, array $cols): ?string {
    foreach ($cols as $col) {
        if (col_exists($db, $table, $col)) {
            return $col;
        }
    }
    return null;
}

function students_list(mysqli $db, int $courseId = 0): array {
    $out = [];

    if (!table_exists($db, 'studentss')) {
        return [];
    }
    

    $nameCol = label_col($db, 'studentss', [
        'full_name',
        'student_name',
        'name'
    ]);

    $regCol = null;

    foreach (['center_reg_no', 'reference_no'] as $c) {
        if (col_exists($db, 'studentss', $c)) {
            $regCol = $c;
            break;
        }
    }

    if (
        $courseId > 0 &&
        table_exists($db, 'enrollments') &&
        table_exists($db, 'batches')
    ) {
        $sql = "
            SELECT DISTINCT
                s.id,
                s.`{$nameCol}` AS full_name
                " . ($regCol ? ", s.`{$regCol}` AS center_reg_no" : ", '' AS center_reg_no") . "
            FROM studentss s
            INNER JOIN enrollments e ON e.student_id = s.id
            INNER JOIN batches b ON b.id = e.batch_id
            WHERE b.course_id = ?
            ORDER BY s.`{$nameCol}` ASC
        ";

        $st = $db->prepare($sql);

        if (!$st) {
            return [];
        }

        $st->bind_param('i', $courseId);

    } else {
        $sql = "
            SELECT
                id,
                `{$nameCol}` AS full_name
                " . ($regCol ? ", `{$regCol}` AS center_reg_no" : ", '' AS center_reg_no") . "
            FROM studentss
            ORDER BY `{$nameCol}` ASC
        ";

        $st = $db->prepare($sql);

        if (!$st) {
            return [];
        }
    }

    $st->execute();
    $res = $st->get_result();

    while ($r = $res->fetch_assoc()) {
        $out[(int)$r['id']] = trim(
            $r['full_name'] .
            (!empty($r['center_reg_no']) ? ' (' . $r['center_reg_no'] . ')' : '')
        );
    }

    $st->close();

    return $out;
}

/* ---------- Students ↔ Batches mapping (auto-detect common table names) ---------- */
function find_batch_student_map(mysqli $db): ?array {
  $candidates=['batch_students','student_batches','batch_enrollments','batches_students','batch_student_map','enrollments'];
  foreach($candidates as $t){
    $r=$db->query("SHOW TABLES LIKE '".$db->real_escape_string($t)."'");
    if($r && $r->num_rows){
      $hasBatch=$db->query("SHOW COLUMNS FROM `$t` LIKE 'batch_id'")->num_rows>0;
      $hasStudent=$db->query("SHOW COLUMNS FROM `$t` LIKE 'student_id'")->num_rows>0;
      if($hasBatch && $hasStudent) return ['table'=>$t,'batch'=>'batch_id','student'=>'student_id'];
    }
  } return null;
}

/* --- POST ops --- */
$msg=null;
if ($_SERVER['REQUEST_METHOD']==='POST') {
  $op=$_POST['op'] ?? 'save';

  if ($op==='toggle') {
    require_csrf();
    $id=(int)($_POST['id'] ?? 0); $to=(int)($_POST['to'] ?? 0);
    $st=$mysqli->prepare("UPDATE lms_assessments SET active=? WHERE id=?"); $st->bind_param('ii',$to,$id); $st->execute(); $st->close();
    header('Location: '.url_for('/admin/assessments/index.php').'?msg='.urlencode("Assessment #$id set to ".($to?'ON':'OFF'))); exit;
  }

  if ($op==='delete') {
    require_csrf();
    $id=(int)($_POST['id'] ?? 0);
    $mysqli->begin_transaction();
    try{
      $mysqli->query("DELETE FROM lms_assessment_batches  WHERE assessment_id=$id");
      $mysqli->query("DELETE FROM lms_assessment_students WHERE assessment_id=$id");
      $mysqli->query("DELETE FROM lms_assessment_attachments WHERE assessment_id=$id");
      $mysqli->query("DELETE FROM lms_assessments        WHERE id=$id");
      $mysqli->commit(); $msg='Assessment deleted.';
    }catch(Throwable $e){ $mysqli->rollback(); $msg='Delete failed.'; }
    header('Location: '.url_for('/admin/assessments/index.php').'?msg='.urlencode($msg)); exit;
  }

  if ($op==='save') {
    require_csrf();
    $editId=(int)($_POST['edit_id'] ?? 0);
    $title=trim((string)($_POST['title'] ?? '')); if($title==='') $title='(untitled)';
    $description=trim((string)($_POST['description'] ?? ''));
    $type=(($_POST['type'] ?? 'assignment')==='project')?'project':'assignment';
    $course_id = (int)($_POST['course_id'] ?? 0);
$module_id = (int)($_POST['module_id'] ?? 0);

if ($course_id <= 0 || $module_id <= 0) {
    header('Location: '.url_for('/admin/assessments/index.php').'?course_id='.$course_id.'&msg='.urlencode('Please select course and module before saving assessment.'));
    exit;
}

$max_score = (int)($_POST['max_score'] ?? 100);

    $available_from=dt_or_null($_POST['available_from'] ?? '');
    $available_to  =dt_or_null($_POST['available_to'] ?? '');
    $due_at        =dt_or_null($_POST['due_at'] ?? '');
    $release_at    =dt_or_null($_POST['release_at'] ?? '');

    $batch_ids   = array_values(array_unique(array_map('intval',(array)($_POST['batch_ids'] ?? []))));
    $student_ids = array_values(array_unique(array_map('intval',(array)($_POST['student_ids'] ?? []))));
    $batches_only = isset($_POST['batches_only']) ? 1 : 0;
    if ($batches_only || $batch_ids) $student_ids=[];

    if ($available_from && $available_to && strtotime($available_from) > strtotime($available_to)) {
      header('Location: '.url_for('/admin/assessments/index.php').'?msg='.urlencode('Available From must be before Available To.')); exit;
    }

    $mysqli->begin_transaction();
    try{
      if ($editId>0){
        $st=$mysqli->prepare("UPDATE lms_assessments
          SET title=?, description=?, type=?,
              course_id=NULLIF(?,0), module_id=NULLIF(?,0),
              available_from=?, available_to=?, due_at=?, release_at=?,
              max_score=? WHERE id=?");
        $st->bind_param('sssiissssii',$title,$description,$type,$course_id,$module_id,$available_from,$available_to,$due_at,$release_at,$max_score,$editId);
        $st->execute(); $st->close(); $id=$editId;
      }else{
        $st=$mysqli->prepare("INSERT INTO lms_assessments
          (title,description,type,course_id,module_id,available_from,available_to,due_at,release_at,max_score)
          VALUES (?,?,?,NULLIF(?,0),NULLIF(?,0),?,?,?,?,?)");
        $st->bind_param('sssiissssi',$title,$description,$type,$course_id,$module_id,$available_from,$available_to,$due_at,$release_at,$max_score);
        $st->execute(); $id=$st->insert_id; $st->close();
      }

      $mysqli->query("DELETE FROM lms_assessment_batches  WHERE assessment_id=$id");
      $mysqli->query("DELETE FROM lms_assessment_students WHERE assessment_id=$id");
      if ($batch_ids){ $st=$mysqli->prepare("INSERT INTO lms_assessment_batches(assessment_id,batch_id) VALUES (?,?)");
        foreach($batch_ids as $b){ $st->bind_param('ii',$id,$b); $st->execute(); } $st->close(); }
      if ($student_ids){ $st=$mysqli->prepare("INSERT INTO lms_assessment_students(assessment_id,student_id) VALUES (?,?)");
        foreach($student_ids as $s){ $st->bind_param('ii',$id,$s); $st->execute(); } $st->close(); }

      if (!empty($_FILES['brief']['name'])) save_assessment_attachment($mysqli,(int)$id,$_FILES['brief']);

      $mysqli->commit();
      header('Location: '.url_for('/admin/assessments/index.php').'?msg='.urlencode($editId>0?'Assessment updated.':'Assessment created.')); exit;
    }catch(Throwable $e){ $mysqli->rollback();
      header('Location: '.url_for('/admin/assessments/index.php').'?msg='.urlencode('Save failed.')); exit;
    }
  }
}

/* --- filters + lists --- */
$filterCourse = isset($_GET['course_id']) ? (int)$_GET['course_id'] : 0;
$courses  = courses_list($mysqli);
$batches  = batches_list($mysqli, $filterCourse ?: null);
$students = students_list($mysqli, (int)$filterCourse);
if (table_exists($mysqli, 'courses')) {
    $courseLabelCol = label_col($mysqli,'courses',['course_name','name','title','label']);
} else {
    $courseLabelCol = 'id';
}

$where = $filterCourse ? " WHERE a.course_id=".$filterCourse : '';
$hasCourseModules = table_exists($mysqli, 'course_modules');

$moduleJoin   = $hasCourseModules
    ? "LEFT JOIN course_modules cm ON cm.id=a.module_id"
    : "";

$moduleSelect = $hasCourseModules
    ? "cm.title AS module_label"
    : "'-' AS module_label";

$sql = "SELECT a.*, COALESCE(c.$courseLabelCol,'#') AS course_label, $moduleSelect
        FROM lms_assessments a
        LEFT JOIN courses c ON c.id=a.course_id
        $moduleJoin
        $where
        ORDER BY a.id DESC
        LIMIT 100";
$list = ($rs=$mysqli->query($sql)) ? $rs->fetch_all(MYSQLI_ASSOC) : [];

/* --- edit prefill --- */
$editRow=null; $selB=$selS=[];
if (isset($_GET['edit'])) {
  $eid=(int)$_GET['edit'];
  $st=$mysqli->prepare("SELECT * FROM lms_assessments WHERE id=?"); $st->bind_param('i',$eid); $st->execute();
  $editRow=$st->get_result()->fetch_assoc(); $st->close();
  if ($editRow){
    $rs=$mysqli->query("SELECT batch_id FROM lms_assessment_batches WHERE assessment_id=".(int)$editRow['id']); while($r=$rs->fetch_assoc()) $selB[]=(int)$r['batch_id'];
    $rs=$mysqli->query("SELECT student_id FROM lms_assessment_students WHERE assessment_id=".(int)$editRow['id']); while($r=$rs->fetch_assoc()) $selS[]=(int)$r['student_id'];
  }
}

/* --- initial modules (course_modules) --- */
$formCourseId = (int)($editRow['course_id'] ?? $filterCourse ?? 0);
$modules = course_modules_list($mysqli, $formCourseId ?: null);
$midSel  = (int)($editRow['module_id'] ?? 0);

/* --- JS maps for dynamic Modules & Students --- */
$MODS_BY_COURSE = [];
if (table_exists($mysqli,'course_modules')) {
  $rs=$mysqli->query("SELECT id,course_id,COALESCE(title,CONCAT('Module #',id)) AS t FROM course_modules ORDER BY sort_order ASC, id ASC");
  while($r=$rs->fetch_assoc()) $MODS_BY_COURSE[(int)$r['course_id']][]=['id'=>(int)$r['id'],'t'=>$r['t']];
  if($rs) $rs->close();
}
$MODS_BY_BATCH = [];
if (table_exists($mysqli,'batch_modules') && table_exists($mysqli,'course_modules')) {
  $rs=$mysqli->query("SELECT bm.batch_id AS bid, cm.id AS id, COALESCE(cm.title,CONCAT('Module #',cm.id)) AS t
                      FROM batch_modules bm JOIN course_modules cm ON cm.id=bm.course_module_id
                      ORDER BY cm.title, cm.id");
  while($r=$rs->fetch_assoc()) $MODS_BY_BATCH[(int)$r['bid']][]=['id'=>(int)$r['id'],'t'=>$r['t']];
  if($rs) $rs->close();
}
/* Students by batch */
$STUDENTS_BY_ID    = $students; // id => label
$STUDENTS_BY_BATCH = [];
if ($map = find_batch_student_map($mysqli)) {
  $t=$map['table']; $bc=$map['batch']; $sc=$map['student'];
  $rs=$mysqli->query("SELECT `$bc` AS bid, `$sc` AS sid FROM `$t`");
  if ($rs){ while($r=$rs->fetch_assoc()){ $STUDENTS_BY_BATCH[(int)$r['bid']][]=(int)$r['sid']; } $rs->free(); }
}

$JS_MODS_BY_COURSE  = json_encode($MODS_BY_COURSE,  JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
$JS_MODS_BY_BATCH   = json_encode($MODS_BY_BATCH,   JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
$JS_STUDENTS_BY_ID  = json_encode($STUDENTS_BY_ID,  JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);
$JS_STUDENTS_BY_BAT = json_encode($STUDENTS_BY_BATCH, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES);

/* --- page header via shared layout --- */
require APP_ROOT . '/includes/admin_layout_top.php';
?>



<style>
  .assessment-hero {
    background: linear-gradient(135deg, #eff6ff 0%, #f8fafc 48%, #eef2ff 100%);
    border: 1px solid #dbeafe;
    border-radius: 22px;
    padding: 22px;
    box-shadow: 0 10px 28px rgba(15, 23, 42, .06);
  }

  .assessment-hero h4 {
    font-weight: 800;
    margin-bottom: 4px;
  }

  .assessment-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 11px;
    border-radius: 999px;
    background: #fff;
    border: 1px solid #e5e7eb;
    color: #475569;
    font-size: 12px;
    font-weight: 700;
  }

  .assessment-card {
    background: #fff;
    border: 1px solid #e5e7eb;
    border-radius: 20px;
    box-shadow: 0 8px 24px rgba(15, 23, 42, .055);
    overflow: hidden;
  }

  .assessment-card-header {
    padding: 18px 20px;
    border-bottom: 1px solid #e5e7eb;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
  }

  .assessment-card-title {
    font-size: 16px;
    font-weight: 800;
    margin: 0;
  }

  .assessment-card-subtitle {
    color: #64748b;
    font-size: 12px;
    margin-top: 2px;
  }

  .assessment-card-body {
    padding: 20px;
  }

  .soft-panel {
    background: #f8fafc;
    border: 1px solid #e5e7eb;
    border-radius: 18px;
    padding: 16px;
  }

  .section-title {
    font-size: 13px;
    font-weight: 800;
    color: #334155;
    text-transform: uppercase;
    letter-spacing: .04em;
    margin-bottom: 12px;
  }

  .form-label {
    font-size: 13px;
    font-weight: 700;
    color: #334155;
  }

  .form-control,
  .form-select {
    border-radius: 13px;
  }

  .picker-toolbar {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 8px;
  }

  .picker-toolbar .form-control {
    min-width: 180px;
    flex: 1;
  }

  .picker-select {
    min-height: 190px;
    border-radius: 14px;
  }

  .selection-summary {
    font-size: 12px;
    color: #64748b;
    margin-top: 7px;
    min-height: 22px;
  }

  .assessment-table thead th {
    background: #f8fafc;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: #64748b;
    white-space: nowrap;
  }

  .assessment-table tbody td {
    vertical-align: middle;
  }

  .assessment-title-cell {
    min-width: 260px;
  }

  .assessment-actions {
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    gap: 6px;
  }

  .badge-soft {
    background: #f1f5f9;
    color: #334155;
    border: 1px solid #e2e8f0;
  }

  .date-badge {
    display: inline-flex;
    padding: 6px 9px;
    border-radius: 999px;
    font-size: 12px;
    font-weight: 700;
    margin: 2px;
  }

  .date-badge-muted {
    background: #f1f5f9;
    color: #475569;
  }

  .date-badge-warning {
    background: #fef3c7;
    color: #92400e;
  }

  .date-badge-danger {
    background: #fee2e2;
    color: #b91c1c;
  }

  @media (max-width: 768px) {
    .assessment-card-header {
      flex-direction: column;
      align-items: flex-start;
    }

    .assessment-hero {
      padding: 18px;
    }

    .assessment-actions {
      justify-content: flex-start;
    }
  }
</style>

<?php if (isset($_GET['msg']) || $msg): ?>
  <div class="alert alert-info border-0 rounded-4 shadow-sm mb-3">
    <i class="bi bi-info-circle me-1"></i>
    <?= esc($_GET['msg'] ?? $msg) ?>
  </div>
<?php endif; ?>

<div class="assessment-hero mb-4">
  <div class="d-flex flex-wrap align-items-center justify-content-between gap-3">
    <div>
      <h4>Assessments & Projects</h4>
      <div class="text-muted">
        Create assignments, set deadlines, attach briefs, and publish to selected batches or students.
      </div>
    </div>

    <div class="d-flex flex-wrap gap-2">
      <span class="assessment-chip">
        <i class="bi bi-journal-check text-primary"></i>
        <?= number_format(count($list)) ?> Assessments
      </span>

      <span class="assessment-chip">
        <i class="bi bi-book text-success"></i>
        <?= number_format(count($courses)) ?> Courses
      </span>

      <a href="submissions.php" class="btn btn-sm btn-outline-primary rounded-pill">
        <i class="bi bi-cloud-arrow-up me-1"></i>
        Submissions
      </a>

      <a href="gradebook.php" class="btn btn-sm btn-outline-success rounded-pill">
        <i class="bi bi-journal-check me-1"></i>
        Gradebook
      </a>
    </div>
  </div>
</div>


<div class="assessment-card mb-4">
  <div class="assessment-card-header">
    <div>
      <h5 class="assessment-card-title">
        <?= $editRow ? 'Edit Assessment' : 'Create New Assessment' ?>
      </h5>
      <div class="assessment-card-subtitle">
        Fill the assessment details and choose publishing targets.
      </div>
    </div>

    <?php if ($editRow): ?>
      <a class="btn btn-sm btn-outline-secondary rounded-pill" href="<?= url_for('/admin/assessments/index.php') ?>">
        <i class="bi bi-arrow-left me-1"></i>
        Cancel Edit
      </a>
    <?php endif; ?>
  </div>

  <div class="assessment-card-body">
    <form method="post" autocomplete="off" enctype="multipart/form-data">
      <input type="hidden" name="op" value="save">
      <input type="hidden" name="csrf" value="<?= esc(csrf_token()) ?>">
      <input type="hidden" name="edit_id" value="<?= isset($_GET['edit']) ? (int)$_GET['edit'] : 0 ?>">

      <div class="soft-panel mb-3">
        <div class="section-title">
          <i class="bi bi-diagram-3 me-1"></i>
          Course & Module
        </div>

        <div class="row g-3">
          <div class="col-md-6">
            <label class="form-label">Course</label>
            <select class="form-select" name="course_id" id="course-id"
                    onchange="location.href='<?= url_for('/admin/assessments/index.php') ?>?course_id='+this.value<?= isset($_GET['edit'])?"+'&edit=".((int)$_GET['edit'])."'" : '' ?>;">
              <option value="0">— Select Course —</option>
              <?php $cid=(int)($editRow['course_id'] ?? $filterCourse); ?>
              <?php foreach($courses as $id=>$lab): ?>
                <option value="<?= $id ?>" <?= $cid===$id?'selected':'' ?>>
                  <?= esc($lab) ?>
                </option>
              <?php endforeach; ?>
            </select>
            <div class="small text-muted mt-1">Modules, batches, and students follow the selected course.</div>
          </div>

          <div class="col-md-6">
            <label class="form-label">Course Module <span class="text-danger">*</span></label>
            <select class="form-select" name="module_id" id="module_id" required>
              <option value="0">— Select Module —</option>
              <?php foreach($modules as $mid=>$mlab): ?>
                <option value="<?= (int)$mid ?>" <?= $midSel===$mid?'selected':'' ?>>
                  <?= esc($mlab) ?>
                </option>
              <?php endforeach; ?>
            </select>
          </div>
        </div>
      </div>

      <div class="soft-panel mb-3">
        <div class="section-title">
          <i class="bi bi-file-earmark-text me-1"></i>
          Assessment Details
        </div>

        <div class="row g-3">
          <div class="col-md-6">
            <label class="form-label">Title</label>
            <input class="form-control" name="title" placeholder="Example: Final Project Brief" value="<?= esc($editRow['title'] ?? '') ?>">
          </div>

          <div class="col-md-3">
            <label class="form-label">Type</label>
            <?php $t=$editRow['type'] ?? 'assignment'; ?>
            <select class="form-select" name="type">
              <option value="assignment" <?= $t==='assignment'?'selected':'' ?>>Assignment</option>
              <option value="project" <?= $t==='project'?'selected':'' ?>>Project</option>
            </select>
          </div>

          <div class="col-md-3">
            <label class="form-label">Max Score</label>
            <input class="form-control" type="number" name="max_score" value="<?= (int)($editRow['max_score'] ?? 100) ?>">
          </div>

          <div class="col-12">
            <label class="form-label">Description <span class="text-muted">(Optional)</span></label>
            <textarea class="form-control" name="description" id="desc" rows="3" placeholder="Write short instructions or assessment description..."><?= esc($editRow['description'] ?? '') ?></textarea>
            <div class="small text-muted mt-1" id="desc-count"></div>
          </div>
        </div>
      </div>

      <div class="soft-panel mb-3">
        <div class="section-title">
          <i class="bi bi-calendar-check me-1"></i>
          Availability & Deadlines
        </div>

        <div class="row g-3">
          <div class="col-md-3">
            <label class="form-label">Available From</label>
            <input class="form-control" type="datetime-local" name="available_from" value="<?= esc(dt_to_input($editRow['available_from'] ?? null)) ?>">
          </div>

          <div class="col-md-3">
            <label class="form-label">Available To</label>
            <input class="form-control" type="datetime-local" name="available_to" value="<?= esc(dt_to_input($editRow['available_to'] ?? null)) ?>">
          </div>

          <div class="col-md-3">
            <label class="form-label">Due Deadline</label>
            <input class="form-control" type="datetime-local" name="due_at" value="<?= esc(dt_to_input($editRow['due_at'] ?? null)) ?>">
          </div>

          <div class="col-md-3">
            <label class="form-label">Marks Release At</label>
            <input class="form-control" type="datetime-local" name="release_at" value="<?= esc(dt_to_input($editRow['release_at'] ?? null)) ?>">
          </div>
        </div>
      </div>

      <div class="soft-panel mb-3">
        <div class="section-title">
          <i class="bi bi-send-check me-1"></i>
          Publish Targets
        </div>

        <div class="row g-3">
          <div class="col-lg-6">
            <label class="form-label">Publish to Batches</label>

            <div class="picker-toolbar">
              <input class="form-control form-control-sm" id="filter-batches" placeholder="Filter batches...">
              <button type="button" class="btn btn-sm btn-outline-primary rounded-pill" id="btnBatchPicker">
                Picker
              </button>
              <button type="button" class="btn btn-sm btn-outline-secondary rounded-pill" id="btnBatchAll">
                All
              </button>
              <button type="button" class="btn btn-sm btn-outline-secondary rounded-pill" id="btnBatchNone">
                Clear
              </button>
            </div>

            <select class="form-select picker-select" id="select-batches" name="batch_ids[]" size="6" multiple>
              <?php foreach($batches as $id=>$lab): ?>
                <option value="<?= $id ?>" <?= in_array($id,$selB,true)?'selected':'' ?>>
                  <?= esc($lab) ?>
                </option>
              <?php endforeach; ?>
            </select>

            <div class="form-check mt-2">
              <input type="checkbox" class="form-check-input" name="batches_only" id="batches-only" <?= $selB && !$selS ? 'checked' : '' ?>>
              <label class="form-check-label small" for="batches-only">
                Publish only to selected batches. Individual students will be ignored.
              </label>
            </div>

            <div id="batch-summary" class="selection-summary"></div>
          </div>

          <div class="col-lg-6">
            <label class="form-label">Publish to Individual Students</label>

            <div class="picker-toolbar">
              <input class="form-control form-control-sm" id="filter-students" placeholder="Filter students...">
              <button type="button" class="btn btn-sm btn-outline-primary rounded-pill" id="btnStudentPicker">
                Picker
              </button>
              <button type="button" class="btn btn-sm btn-outline-secondary rounded-pill" id="btnStuAll">
                All
              </button>
              <button type="button" class="btn btn-sm btn-outline-secondary rounded-pill" id="btnStuNone">
                Clear
              </button>
            </div>

            <select class="form-select picker-select" id="select-students" name="student_ids[]" size="6" multiple>
              <?php foreach($students as $id=>$lab): ?>
                <option value="<?= $id ?>" <?= in_array($id,$selS,true)?'selected':'' ?>>
                  <?= esc($lab) ?>
                </option>
              <?php endforeach; ?>
            </select>

            <div class="small text-muted mt-2">
              If any batch is selected or “batches only” is ticked, students are ignored.
            </div>

            <div id="student-summary" class="selection-summary"></div>
          </div>
        </div>
      </div>

      <div class="soft-panel mb-3">
        <div class="section-title">
          <i class="bi bi-paperclip me-1"></i>
          Attachment
        </div>

        <div class="row g-3">
          <div class="col-lg-8">
            <label class="form-label">Attach Brief / Project File <span class="text-muted">(Optional)</span></label>
            <input type="file" name="brief" class="form-control"
                   accept=".pdf,.doc,.docx,.ppt,.pptx,.xls,.xlsx,.zip,.rar,.7z,.txt,.jpg,.jpeg,.png,.mp4,.mov,.avi">

            <?php if (!empty($editRow['id'])): ?>
              <?php $___brief = get_latest_attachment($mysqli, (int)$editRow['id']); ?>
              <?php if($___brief): ?>
                <div class="small text-muted mt-2">
                  Current file:
                  <a href="<?= esc($___brief) ?>" target="_blank">
                    <?= esc(basename($___brief)) ?>
                  </a>
                  <span class="text-muted">(upload a new file to add another brief)</span>
                </div>
              <?php endif; ?>
            <?php endif; ?>
          </div>
        </div>
      </div>

      <div class="d-flex flex-wrap justify-content-end gap-2">
        <?php if ($editRow): ?>
          <a class="btn btn-outline-secondary rounded-pill" href="<?= url_for('/admin/assessments/index.php') ?>">
            Cancel
          </a>
        <?php endif; ?>

        <button class="btn btn-admin-primary">
          <i class="bi bi-check-circle me-1"></i>
          <?= $editRow ? 'Update Assessment' : 'Create Assessment' ?>
        </button>
      </div>
    </form>
  </div>
</div>

<div class="assessment-card">
  <div class="assessment-card-header">
    <div>
      <h5 class="assessment-card-title">Assessment List</h5>
      <div class="assessment-card-subtitle">Latest 100 assessments and projects</div>
    </div>
  </div>

  <div class="assessment-card-body">
    <div class="table-responsive">
      <table class="table assessment-table table-hover align-middle mb-0">
        <thead>
          <tr>
            <th style="width:28%">Title & Description</th>
            <th>Course</th>
            <th>Window</th>
            <th>Due</th>
            <th>Release</th>
            <th>Active</th>
            <th class="text-end">Action</th>
          </tr>
        </thead>

        <tbody>
          <?php if(!$list): ?>
            <tr>
              <td colspan="7" class="text-center text-muted py-4">
                No assessments yet.
              </td>
            </tr>
          <?php endif; ?>

          <?php foreach($list as $r): ?>
            <?php $on = (int)$r['active']; ?>

            <tr>
              <td class="assessment-title-cell">
                <div class="fw-bold"><?= esc($r['title']) ?></div>

                <div class="mt-1">
                  <span class="badge badge-soft text-uppercase">
                    <?= esc($r['type']) ?>
                  </span>

                  <?php if(!empty($r['module_label'])): ?>
                    <span class="badge badge-soft">
                      Module: <?= esc($r['module_label']) ?>
                    </span>
                  <?php endif; ?>
                </div>

                <?php if(!empty($r['description'])): ?>
                  <div class="small text-muted mt-2">
                    <?= esc(short_text($r['description'], 120)) ?>
                  </div>
                <?php endif; ?>
              </td>

              <td>
                <?= esc($r['course_label'] ?: '—') ?>
              </td>

              <td class="small">
                <?php if(!empty($r['available_from'])): ?>
                  <span class="date-badge date-badge-muted">
                    From: <?= esc($r['available_from']) ?>
                  </span>
                <?php else: ?>
                  <span class="date-badge date-badge-warning">From: —</span>
                <?php endif; ?>

                <?php if(!empty($r['available_to'])): ?>
                  <span class="date-badge date-badge-muted">
                    To: <?= esc($r['available_to']) ?>
                  </span>
                <?php else: ?>
                  <span class="date-badge date-badge-warning">To: —</span>
                <?php endif; ?>
              </td>

              <td class="small">
                <?php if(!empty($r['due_at'])): ?>
                  <span class="date-badge date-badge-danger">
                    Due: <?= esc($r['due_at']) ?>
                  </span>
                <?php else: ?>
                  <span class="date-badge date-badge-warning">Due: —</span>
                <?php endif; ?>
              </td>

              <td class="small">
                <?php if(!empty($r['release_at'])): ?>
                  <span class="date-badge date-badge-muted">
                    <?= esc($r['release_at']) ?>
                  </span>
                <?php else: ?>
                  <span class="date-badge date-badge-warning">Release: —</span>
                <?php endif; ?>
              </td>

              <td>
                <form method="post" class="d-inline">
                  <input type="hidden" name="op" value="toggle">
                  <input type="hidden" name="csrf" value="<?= esc(csrf_token()) ?>">
                  <input type="hidden" name="id" value="<?= (int)$r['id'] ?>">
                  <input type="hidden" name="to" value="<?= $on ? 0 : 1 ?>">

                  <button class="badge bg-<?= $on ? 'success' : 'secondary' ?> border-0" type="submit">
                    <?= $on ? 'ON' : 'OFF' ?>
                  </button>
                </form>
              </td>

              <td>
                <div class="assessment-actions">
                  <?php $brief = get_latest_attachment($mysqli, (int)$r['id']); ?>
                  <?php if($brief): ?>
                    <a class="btn btn-sm btn-outline-secondary rounded-pill" target="_blank" href="<?= esc($brief) ?>">
                      Brief
                    </a>
                  <?php endif; ?>

                  <a class="btn btn-sm btn-outline-secondary rounded-pill" href="<?= url_for('/admin/assessments/view.php').'?id='.(int)$r['id'] ?>">
                    View
                  </a>

                  <a class="btn btn-sm btn-outline-primary rounded-pill" href="<?= url_for('/admin/assessments/index.php').'?edit='.(int)$r['id'].'&course_id='.(int)$r['course_id'] ?>">
                    Edit
                  </a>

                  <form method="post" class="d-inline" onsubmit="return confirm('Delete this assessment?');">
                    <input type="hidden" name="op" value="delete">
                    <input type="hidden" name="csrf" value="<?= esc(csrf_token()) ?>">
                    <input type="hidden" name="id" value="<?= (int)$r['id'] ?>">

                    <button class="btn btn-sm btn-outline-danger rounded-pill" type="submit">
                      Delete
                    </button>
                  </form>
                </div>
              </td>
            </tr>
          <?php endforeach; ?>
        </tbody>
      </table>
    </div>
  </div>
</div>

<!-- Batch Picker Modal -->
<div class="modal fade" id="batchPickerModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg">
    <div class="modal-content">
      <div class="modal-header"><h5 class="modal-title">Select Batches</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
      <div class="modal-body">
        <input class="form-control mb-2" id="batch-modal-search" placeholder="Search batches…">
        <div id="batch-modal-list" class="list-group"></div>
      </div>
      <div class="modal-footer">
        <button type="button" id="batch-modal-all" class="btn btn-outline-secondary">Select all</button>
        <button type="button" id="batch-modal-none" class="btn btn-outline-secondary">Clear</button>
        <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Apply</button>
      </div>
    </div>
  </div>
</div>

<!-- Student Picker Modal -->
<div class="modal fade" id="studentPickerModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg">
    <div class="modal-content">
      <div class="modal-header"><h5 class="modal-title">Select Students</h5><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
      <div class="modal-body">
        <input class="form-control mb-2" id="student-modal-search" placeholder="Search students…">
        <div id="student-modal-list" class="list-group"></div>
      </div>
      <div class="modal-footer">
        <button type="button" id="student-modal-all" class="btn btn-outline-secondary">Select all</button>
        <button type="button" id="student-modal-none" class="btn btn-outline-secondary">Clear</button>
        <button type="button" class="btn btn-primary" data-bs-dismiss="modal">Apply</button>
      </div>
    </div>
  </div>
</div>

<script>
  // description counter
  (function(){const el=document.getElementById('desc'), out=document.getElementById('desc-count'); if(!el||!out) return;
    const upd=()=>out.textContent=el.value.length+' characters'; el.addEventListener('input',upd); upd();})();

  // simple inline filters
  function attachFilter(inp, sel){
    const box=document.getElementById(inp), s=document.getElementById(sel); if(!box||!s) return;
    const opts=[...s.options]; box.addEventListener('input',()=>{const q=box.value.trim().toLowerCase(); s.innerHTML='';
      opts.forEach(o=>{ if(!q || o.text.toLowerCase().includes(q)) s.appendChild(o); });});
  }
  attachFilter('filter-batches','select-batches');
  attachFilter('filter-students','select-students');

  // summaries & disable logic
  function summarize(selectId, outId, label){
    const sel=document.getElementById(selectId), out=document.getElementById(outId); if(!sel||!out) return;
    const chosen=[...sel.selectedOptions]; const chips=chosen.slice(0,6).map(o=>`<span class="badge bg-light text-dark me-1">${o.text}</span>`).join('');
    out.innerHTML = chosen.length ? `${chosen.length} ${label} selected · ${chips}` : '<span class="text-muted">None selected</span>';
  }
  function updateSummaries(){
    summarize('select-batches','batch-summary','batch(es)');
    summarize('select-students','student-summary','student(s)');
    const anyBatch = document.getElementById('select-batches')?.selectedOptions.length>0;
    const cb=document.getElementById('batches-only'); if (cb) cb.checked = cb.checked || anyBatch;
    const s=document.getElementById('select-students'); if (s && cb?.checked) s.setAttribute('disabled','disabled'); else s?.removeAttribute('disabled');
  }

  // ====== MAPS from PHP ======
  const MODS_BY_COURSE = <?= $JS_MODS_BY_COURSE ?? '{}' ?>;
  const MODS_BY_BATCH  = <?= $JS_MODS_BY_BATCH  ?? '{}' ?>;
  const STUDENTS_BY_ID = <?= $JS_STUDENTS_BY_ID ?? '{}' ?>;
  const STUDENTS_BY_BATCH = <?= $JS_STUDENTS_BY_BAT ?? '{}' ?>;

  // DOM refs
  const courseSel = document.getElementById('course-id');
  const batchSel  = document.getElementById('select-batches');
  const moduleSel = document.getElementById('module_id');
  const studentSel= document.getElementById('select-students');
  const onlyBatches=document.getElementById('batches-only');
  const PRESELECT = <?= (int)$midSel ?>;

  // helpers
  const selectedValues = (sel)=> Array.from(sel?.selectedOptions||[]).map(o=>o.value);
  const setSelected = (sel,vals)=>{ const S=new Set(vals.map(String)); Array.from(sel.options).forEach(o=>o.selected=S.has(o.value)); sel.dispatchEvent(new Event('change')); };
  const selectAll = (sel)=>{ Array.from(sel.options).forEach(o=>o.selected=true); sel.dispatchEvent(new Event('change')); };
  const clearAll  = (sel)=>{ Array.from(sel.options).forEach(o=>o.selected=false); sel.dispatchEvent(new Event('change')); };

  document.getElementById('btnBatchAll')?.addEventListener('click',()=>selectAll(batchSel));
  document.getElementById('btnBatchNone')?.addEventListener('click',()=>clearAll(batchSel));
  document.getElementById('btnStuAll')?.addEventListener('click',()=>selectAll(studentSel));
  document.getElementById('btnStuNone')?.addEventListener('click',()=>clearAll(studentSel));

  // modules builder
  function buildModuleOptions(items){
    const seen=new Set(), out=[]; (items||[]).forEach(x=>{ if(x && !seen.has(x.id)){ seen.add(x.id); out.push(x);} });
    out.sort((a,b)=>(a.t||'').localeCompare(b.t||'')); moduleSel.innerHTML='<option value="0">—</option>'+out.map(x=>`<option value="${x.id}">${x.t}</option>`).join('');
    if (PRESELECT && out.some(x=>x.id===PRESELECT)) moduleSel.value=String(PRESELECT);
  }
function refillModules(){
    const cid = parseInt(courseSel?.value || '0', 10);
    const currentVal = moduleSel?.value || '0';
    const bids = selectedValues(batchSel).map(v => parseInt(v, 10)).filter(Boolean);

    let items = [];

    if (bids.length) {
        bids.forEach(b => {
            (MODS_BY_BATCH[String(b)] || []).forEach(x => items.push(x));
        });
    }

    if (!items.length) {
        items = MODS_BY_COURSE[String(cid)] || [];
    }

    buildModuleOptions(items);

    if (currentVal !== '0' && Array.from(moduleSel.options).some(o => o.value === currentVal)) {
        moduleSel.value = currentVal;
    }
}

  // students builder (union of selected batches)
  function refillStudentsByBatches(){
    if (!studentSel) return;
    const bids=selectedValues(batchSel).map(v=>parseInt(v,10)).filter(Boolean);
    if (bids.length && Object.keys(STUDENTS_BY_BATCH).length){
      const union=new Set(); bids.forEach(b=> (STUDENTS_BY_BATCH[String(b)]||[]).forEach(sid=>union.add(String(sid))));
      const keep=new Set(Array.from(studentSel.selectedOptions).map(o=>o.value).filter(v=>union.has(v)));
      const opts=[]; union.forEach(sid=>{ const label=STUDENTS_BY_ID[String(sid)]||('Student #'+sid); opts.push(new Option(label,String(sid),false,keep.has(String(sid)))); });
      opts.sort((a,b)=>a.text.localeCompare(b.text)); studentSel.innerHTML=''; opts.forEach(o=>studentSel.appendChild(o));
    } else {
      const prevSel=new Set(Array.from(studentSel.selectedOptions).map(o=>o.value));
      const opts=Object.entries(STUDENTS_BY_ID).map(([sid,label])=>new Option(label,String(sid),false,prevSel.has(String(sid))));
      opts.sort((a,b)=>a.text.localeCompare(b.text)); studentSel.innerHTML=''; opts.forEach(o=>studentSel.appendChild(o));
    }
    if (onlyBatches?.checked) studentSel.setAttribute('disabled','disabled'); else studentSel.removeAttribute('disabled');
    updateSummaries();
  }

  // wire changes
  batchSel?.addEventListener('change',()=>{ refillModules(); refillStudentsByBatches(); });
  courseSel?.addEventListener('change',refillModules);
  onlyBatches?.addEventListener('change',refillStudentsByBatches);

  // initial
  refillModules(); refillStudentsByBatches(); updateSummaries();

  // ======= Picker Modals (Bootstrap) =======
  const batchModal = new bootstrap.Modal(document.getElementById('batchPickerModal'));
  const studentModal=new bootstrap.Modal(document.getElementById('studentPickerModal'));

  document.getElementById('btnBatchPicker')?.addEventListener('click',()=>{
    const box=document.getElementById('batch-modal-list'); const q=document.getElementById('filter-batches').value.trim().toLowerCase();
    box.innerHTML=''; Array.from(batchSel.options).forEach(o=>{ if(!q||o.text.toLowerCase().includes(q)){ const id='bm_'+o.value;
      const row=document.createElement('label'); row.className='list-group-item d-flex align-items-center gap-2';
      row.innerHTML=`<input type="checkbox" class="form-check-input" ${o.selected?'checked':''} data-val="${o.value}" id="${id}"><span>${o.text}</span>`;
      box.appendChild(row); }});
    document.getElementById('batch-modal-search').value=q; batchModal.show();
  });
  document.getElementById('batch-modal-search')?.addEventListener('input',e=>{
    const q=e.target.value.trim().toLowerCase();
    Array.from(document.querySelectorAll('#batch-modal-list .list-group-item')).forEach(li=>{
      li.style.display = (!q||li.textContent.toLowerCase().includes(q)) ? '' : 'none';
    });
  });
  document.getElementById('batch-modal-all')?.addEventListener('click',()=>{ document.querySelectorAll('#batch-modal-list input[type=checkbox]').forEach(cb=>cb.checked=true); });
  document.getElementById('batch-modal-none')?.addEventListener('click',()=>{ document.querySelectorAll('#batch-modal-list input[type=checkbox]').forEach(cb=>cb.checked=false); });
  document.getElementById('batchPickerModal')?.addEventListener('hidden.bs.modal',()=>{
    const values=Array.from(document.querySelectorAll('#batch-modal-list input[type=checkbox]')).filter(cb=>cb.checked).map(cb=>cb.getAttribute('data-val'));
    setSelected(batchSel, values); refillModules(); refillStudentsByBatches();
  });

  document.getElementById('btnStudentPicker')?.addEventListener('click',()=>{
    const box=document.getElementById('student-modal-list'); box.innerHTML='';
    Array.from(studentSel.options).forEach(o=>{
      const id='sm_'+o.value; const row=document.createElement('label'); row.className='list-group-item d-flex align-items-center gap-2';
      row.innerHTML=`<input type="checkbox" class="form-check-input" ${o.selected?'checked':''} data-val="${o.value}" id="${id}"><span>${o.text}</span>`;
      box.appendChild(row);
    });
    document.getElementById('student-modal-search').value=''; studentModal.show();
  });
  document.getElementById('student-modal-search')?.addEventListener('input',e=>{
    const q=e.target.value.trim().toLowerCase();
    Array.from(document.querySelectorAll('#student-modal-list .list-group-item')).forEach(li=>{
      li.style.display = (!q||li.textContent.toLowerCase().includes(q)) ? '' : 'none';
    });
  });
  document.getElementById('student-modal-all')?.addEventListener('click',()=>{ document.querySelectorAll('#student-modal-list input[type=checkbox]').forEach(cb=>cb.checked=true); });
  document.getElementById('student-modal-none')?.addEventListener('click',()=>{ document.querySelectorAll('#student-modal-list input[type=checkbox]').forEach(cb=>cb.checked=false); });
  document.getElementById('studentPickerModal')?.addEventListener('hidden.bs.modal',()=>{
    const values=Array.from(document.querySelectorAll('#student-modal-list input[type=checkbox]')).filter(cb=>cb.checked).map(cb=>cb.getAttribute('data-val'));
    setSelected(studentSel, values); updateSummaries();
  });
</script>

<?php require_once APP_ROOT . '/includes/admin_layout_bottom.php'; ?>
