<?php
declare(strict_types=1);

require_once __DIR__ . '/../includes/auth.php';
ec_session_start();
ec_require_login();

ini_set('display_errors', '1');
error_reporting(E_ALL);

ob_start();
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

set_exception_handler(function (Throwable $e) {
  while (ob_get_level()) ob_end_clean();
  http_response_code(500);
  header('Content-Type: text/plain; charset=utf-8');
  echo "EXCEPTION: {$e->getMessage()} in {$e->getFile()}:{$e->getLine()}";
  exit;
});

register_shutdown_function(function () {
  $e = error_get_last();
  if ($e && in_array($e['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR], true)) {
    while (ob_get_level()) ob_end_clean();
    http_response_code(500);
    header('Content-Type: text/plain; charset=utf-8');
    echo "FATAL: {$e['message']} in {$e['file']}:{$e['line']}";
  }
});

register_shutdown_function(function () {
  $e = error_get_last();
  if ($e && in_array($e['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR], true)) {
    http_response_code(500);
    header('Content-Type: text/plain; charset=utf-8');
    echo "FATAL: {$e['message']} in {$e['file']}:{$e['line']}";
  }
});


// ==== DB ====
require_once __DIR__ . '/../includes/db.php';
$mysqli = $conn ?? new mysqli("localhost", "root", "", "edencamp_edencampus");
if ($mysqli->connect_error) {
  http_response_code(500);
  exit("Database Connection Failed: " . $mysqli->connect_error);
}

$mysqli->set_charset("utf8mb4");

// ===== your existing code continues here =====
// e.g. loading $student by id, etc.

$is_embed = (isset($_GET['modal']) && $_GET['modal'] === '1');

// ==== INPUT ====
$student_id = (int)($_POST['id'] ?? $_GET['id'] ?? $_POST['student_id'] ?? $_GET['student_id'] ?? $_GET['sid'] ?? 0);
if ($student_id <= 0) { http_response_code(400); exit('Invalid student id.'); }

$course_id = (int)($_GET['course_id'] ?? $_POST['course_id'] ?? 0);

/* NEW: normalize course filter array used later */
$filter_course_ids = $course_id > 0 ? [$course_id] : [];

/** Child-course scope for filtering refs + batches based on ?course_id */
$scope_child_ids = [];
if ($filter_course_ids) {
  $tmp = array_map('intval', $filter_course_ids);

  if (tableExists($mysqli,'course_children')) {
    $in = implode(',', $tmp);
    $map = [];
    if ($in) {
      $rs = $mysqli->query("SELECT parent_id, child_id FROM course_children WHERE parent_id IN ($in)");
      if ($rs) { while ($r = $rs->fetch_assoc()) $map[(int)$r['parent_id']][] = (int)$r['child_id']; $rs->free(); }
    }
    foreach ($tmp as $cid) {
      if (!empty($map[$cid])) $scope_child_ids = array_merge($scope_child_ids, $map[$cid]);
      else $scope_child_ids[] = $cid; // single course
    }
  } else {
    $scope_child_ids = $tmp;
  }
}
$scope_child_ids = array_values(array_unique(array_filter($scope_child_ids)));

function h($v): string {
  return htmlspecialchars((string)($v ?? ''), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function stmt_fetch_all_assoc(mysqli_stmt $st): array {
  if (!$st->store_result()) return [];
  $meta = $st->result_metadata(); if (!$meta){ $st->free_result(); return []; }
  $fields = $meta->fetch_fields(); $row=[]; $bind=[];
  foreach ($fields as $f) { $row[$f->name]=null; $bind[]=&$row[$f->name]; }
  $st->bind_result(...$bind);
  $out=[]; while ($st->fetch()) { $out[] = array_merge([], $row); }
  $st->free_result(); return $out;
}
function stmt_fetch_one_assoc(mysqli_stmt $st): array { $r=stmt_fetch_all_assoc($st); return $r[0]??[]; }
function tableExists(mysqli $db, string $t): bool {
  $st=$db->prepare("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? LIMIT 1");
  $st->bind_param("s",$t); $st->execute(); $row=stmt_fetch_one_assoc($st); $st->close(); return !empty($row);
}
function stmt_get_one(mysqli_stmt $st): array {
  if (method_exists($st, 'get_result')) {
    $rs = $st->get_result();
    return $rs ? ($rs->fetch_assoc() ?: []) : [];
  }
  $rows = stmt_fetch_all_assoc($st);
  return $rows[0] ?? [];
}

function stmt_get_all(mysqli_stmt $st): array {
  if (method_exists($st, 'get_result')) {
    $rs = $st->get_result();
    return $rs ? $rs->fetch_all(MYSQLI_ASSOC) : [];
  }
  return stmt_fetch_all_assoc($st);
}

function colExists(mysqli $db, string $t, string $c): bool {
  $st=$db->prepare("SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? AND COLUMN_NAME=? LIMIT 1");
  $st->bind_param("ss",$t,$c); $st->execute(); $row=stmt_fetch_one_assoc($st); $st->close(); return !empty($row);
}
function load_student(mysqli $db, int $sid): array {
  $st = $db->prepare("SELECT * FROM studentss WHERE id=? LIMIT 1");
  $st->bind_param('i', $sid);
  $st->execute();
  $row = stmt_fetch_one_assoc($st);
  $st->close();
  return $row ?: [];
}
function build_academic_email(?array $student, int $sid): string {
  $ref = '';
  if (is_array($student)) {
    $ref = trim((string)(
      $student['reference_no'] ??
      $student['ref_no'] ??
      $student['reference_number'] ?? ''
    ));
  }
  $num = '';
  if ($ref !== '' && preg_match('/(\d{1,10})/', $ref, $m)) { $num = $m[1]; }
  if ($num === '') { $num = (string)$sid; }
  return 'Ec' . $num . '@eden.academy';
}
function compute_outstanding_lkr(mysqli $db, int $sid): float {
  $course=$reg=$late=$disc=0.0; $extra=0.0;

  if (tableExists($db, 'student_fee_plans')) {
    $extraCol = colExists($db,'student_fee_plans','extra_fee_lkr')
      ? 'extra_fee_lkr'
      : (colExists($db,'student_fee_plans','extra_fees_lkr') ? 'extra_fees_lkr' : null);

    $cols = "course_fee_lkr,registration_fee_lkr,late_charges,plan_discount_lkr,manual_discount_lkr,method_discount_lkr";
    $cols .= $extraCol ? ", $extraCol AS extra_fee_lkr" : ", 0 AS extra_fee_lkr";

    $st = $db->prepare("SELECT $cols FROM student_fee_plans WHERE student_id=? ORDER BY id DESC LIMIT 1");
    $st->bind_param('i',$sid); $st->execute();
    $row = stmt_get_one($st);
    $st->close();

    if ($row) {
      $course = (float)($row['course_fee_lkr'] ?? 0);
      $reg    = (float)($row['registration_fee_lkr'] ?? 0);
      $late   = (float)($row['late_charges'] ?? 0);
      $extra  = (float)($row['extra_fee_lkr'] ?? 0);
      $disc   = (float)($row['plan_discount_lkr'] ?? 0) + (float)($row['manual_discount_lkr'] ?? 0) + (float)($row['method_discount_lkr'] ?? 0);
    }
  }

  $paid = 0.0;
  if (tableExists($db,'payments')) {
    $st = $db->prepare("SELECT SUM(amount) AS s FROM payments WHERE student_id=?");
    $st->bind_param('i',$sid); $st->execute();
    $row = stmt_get_one($st);
    $st->close();
    $paid = (float)($row['s'] ?? 0);
  }

  $total = max(0.0, ($course + $reg - max(0.0,$disc) + $late + $extra));
  return max(0.0, $total - $paid);
}

// ==== LOAD STUDENT + DATA ====
$st = $mysqli->prepare("SELECT * FROM studentss WHERE id=? LIMIT 1");
$st->bind_param("i",$student_id); $st->execute();
$student = stmt_fetch_one_assoc($st); $st->close();
if (!$student) { die("Student not found."); }

$center_reg_no = $student['center_reg_no'] ?? $student['center_registration_no'] ?? $student['center_no'] ?? $student['center_reg'] ?? '';
$reference_no  = $student['reference_no'] ?? $student['ref_no'] ?? $student['reference_number'] ?? '';

$has_lms_active = colExists($mysqli,'studentss','lms_active');
$lms_active = 1;
if ($has_lms_active) {
  $row = $mysqli->query("SELECT lms_active FROM studentss WHERE id=".(int)$student_id)->fetch_assoc();
  $lms_active = (int)($row['lms_active'] ?? 1);
}
$academic_email = trim((string)($student['academic_email'] ?? ''));
$academic_hash  = trim((string)($student['academic_password_hash'] ?? ''));
$academic_plain_password = isset($student['academic_plain_password']) ? trim((string)$student['academic_plain_password']) : '';
$student_mobile = trim((string)($student['mobile'] ?? ''));
$created_on     = (string)($student['created_at'] ?? '');
$ref_no         = trim((string)($student['reference_no'] ?? ''));

$promotion_plan = '';

// Resolve Course
$resolved_course_id = (int)($student['course_id'] ?? 0);
if ($resolved_course_id <= 0 && tableExists($mysqli,'enrollments') && tableExists($mysqli,'batches')) {
  $st = $mysqli->prepare("
    SELECT b.course_id
      FROM enrollments e
      JOIN batches b ON b.id = e.batch_id
     WHERE e.student_id = ?
     ORDER BY e.id DESC LIMIT 1");
  $st->bind_param("i",$student_id); $st->execute();
  $row = stmt_fetch_one_assoc($st); $st->close();
  if ($row) $resolved_course_id = (int)$row['course_id'];
}

// Course row
$course = [];
if ($resolved_course_id > 0) {
  $st = $mysqli->prepare("SELECT * FROM courses WHERE id=? LIMIT 1");
  $st->bind_param("i",$resolved_course_id); $st->execute();
  $course = stmt_fetch_one_assoc($st); $st->close();
}



// Per-course EC numbers
$bundle_children = [];
$refs_by_course = [];
if (tableExists($mysqli, 'student_numbers')) {
  $st = $mysqli->prepare("SELECT course_id, reference_no, reference_no2 FROM student_numbers WHERE student_id=?");
$st->bind_param('i', $student_id); $st->execute();
if (method_exists($st, 'get_result')) {
  $rs = $st->get_result();
  while ($r = $rs->fetch_assoc()) {
    $cid = (int)($r['course_id'] ?? 0);
    $refs_by_course[$cid] = [
      'ec1' => trim((string)($r['reference_no']  ?? '')),
      'ec2' => trim((string)($r['reference_no2'] ?? '')),
    ];
  }
} else {
  foreach (stmt_fetch_all_assoc($st) as $r) {
    $cid = (int)($r['course_id'] ?? 0);
    $refs_by_course[$cid] = [
      'ec1' => trim((string)($r['reference_no']  ?? '')),
      'ec2' => trim((string)($r['reference_no2'] ?? '')),
    ];
  }
}
$st->close();


}


// === Build course chips for EVERYTHING the student is doing (two singles or bundle) ===
$bundle_children = [];

// 1) collect distinct course_ids from enrollments (preferred)
$enrolled_course_ids = [];

// If a specific course was requested, start with just that.
if ($resolved_course_id > 0) {
  $enrolled_course_ids = [$resolved_course_id];
} else {
  // fallback to your existing logic
  if (tableExists($mysqli,'enrollments') && tableExists($mysqli,'batches')) {
    $st = $mysqli->prepare("
      SELECT DISTINCT b.course_id
        FROM enrollments e
        JOIN batches b ON b.id = e.batch_id
       WHERE e.student_id = ?
    ");
    $st->bind_param('i', $student_id);
    $st->execute();
    if (method_exists($st,'get_result')) {
      $rs = $st->get_result();
      while ($r = $rs->fetch_assoc()) $enrolled_course_ids[] = (int)$r['course_id'];
    } else {
      foreach (stmt_fetch_all_assoc($st) as $r) $enrolled_course_ids[] = (int)$r['course_id'];
    }
    $st->close();
  }

  if ($resolved_course_id > 0) $enrolled_course_ids[] = (int)$resolved_course_id;
}

$enrolled_course_ids = array_values(array_unique(array_filter($enrolled_course_ids)));


// always include fallback resolved course
if ($resolved_course_id > 0) $enrolled_course_ids[] = (int)$resolved_course_id;
$enrolled_course_ids = array_values(array_unique(array_filter($enrolled_course_ids)));

// 2) if we have enrolled courses, expand each: bundle parent → children; single → itself
$ids_for_display = [];
if ($enrolled_course_ids) {
  if (tableExists($mysqli,'course_children')) {
    $in = implode(',', array_map('intval', $enrolled_course_ids));
    $map = [];
    if ($in) {
      $res = $mysqli->query("SELECT parent_id, child_id FROM course_children WHERE parent_id IN ($in)");
      if ($res) { while ($row = $res->fetch_assoc()) $map[(int)$row['parent_id']][] = (int)$row['child_id']; $res->free(); }
    }
    foreach ($enrolled_course_ids as $cid) {
      if (!empty($map[$cid])) $ids_for_display = array_merge($ids_for_display, $map[$cid]);
      else $ids_for_display[] = $cid;
    }
  } else {
    $ids_for_display = $enrolled_course_ids;
  }
}
$ids_for_display = array_values(array_unique($ids_for_display));


  // 3) build the chip objects
  $bundle_children = [];
  $courseNameExpr = colExists($mysqli,'courses','course_name') ? "c.course_name"
               : (colExists($mysqli,'courses','name') ? "c.name" : "''");
$courseCodeExpr = colExists($mysqli,'courses','code') ? "c.code" : "''";

$st = $mysqli->prepare("SELECT c.id, $courseNameExpr AS course_name, $courseCodeExpr AS code
                        FROM courses c WHERE c.id=? LIMIT 1");
if (!$st) { throw new RuntimeException("Prepare failed (courses chip): ".$mysqli->error); }

  foreach ($ids_for_display as $cid) {
    $st->bind_param('i', $cid);
    $st->execute();
    $row = stmt_fetch_one_assoc($st);
    $label = trim((string)($row['code'] ?? '')) ?: trim((string)($row['course_name'] ?? 'Course'));
    $bundle_children[] = [
      'id' => (int)$cid,
      'label' => $label,
      'course_name' => $row['course_name'] ?? '',
      'code' => $row['code'] ?? ''
    ];
  }
  $st->close();


// 4) final fallback if nothing found at all
if (!$bundle_children) {
    // Lesson plan by child
$child_lessons = [];
  $bundle_children = [[
    'id' => (int)$resolved_course_id,
    'label' => $course['code'] ?? ($course['course_name'] ?? ($course['name'] ?? 'Course')),
    'course_name' => $course['course_name'] ?? ($course['name'] ?? '')
  ]];
}

// Lesson plan by child
$child_lessons = [];
foreach ($bundle_children as $bc) {
    $cid = (int)$bc['id'];
    $titles = [];

    $modulesCol = colExists($mysqli,'courses','modules') ? "modules" : null;

if ($modulesCol) {
  $st = $mysqli->prepare("SELECT `$modulesCol` AS modules FROM courses WHERE id=? LIMIT 1");
  if (!$st) { throw new RuntimeException("Prepare failed (courses.modules): ".$mysqli->error); }
  $st->bind_param('i', $cid);
  $st->execute();
  $row = stmt_get_one($st);
  $st->close();
  $mod = $row['modules'] ?? null;
} else {
  // no modules column -> just rely on course_modules table fallback
  $mod = null;
}

    $st->bind_param('i', $cid);
    $st->execute();
    if (method_exists($st, 'get_result')) {
        $row = stmt_get_one($st);

    } else {
        $row = stmt_fetch_one_assoc($st);
    }
    $mod = $row['modules'] ?? null;
    $st->close();

    if ($mod) {
        $j = json_decode($mod, true);
        if (is_array($j)) {
            foreach ($j as $row2) {
                $t = is_array($row2) ? trim((string)($row2['title'] ?? $row2['name'] ?? '')) : trim((string)$row2);
                if ($t !== '') $titles[] = $t;
            }
        } else {
            foreach (explode(',', (string)$mod) as $t) {
                $t = trim($t);
                if ($t !== '') $titles[] = $t;
            }
        }
    }

    if (!$titles && tableExists($mysqli,'course_modules')) {
        $st = $mysqli->prepare("SELECT title FROM course_modules WHERE course_id=? ORDER BY sort_order ASC, id ASC");
        $st->bind_param('i', $cid);
        $st->execute();
        if (method_exists($st, 'get_result')) {
            $rs = $st->get_result();
            while ($r = $rs->fetch_assoc()) {
                $t = trim((string)($r['title'] ?? ''));
                if ($t !== '') $titles[] = $t;
            }
        } else {
            foreach (stmt_fetch_all_assoc($st) as $r) {
                $t = trim((string)($r['title'] ?? ''));
                if ($t !== '') $titles[] = $t;
            }
        }
        $st->close();
    }

    $child_lessons[$cid] = $titles;
}
// ---- DEFAULTS for Overview tab (avoid undefined variables) ----
$is_verified  = false;
$gender_badge = '';
$branch       = '-';

// is_verified (try multiple possible column names)
if (colExists($mysqli, 'studentss', 'is_verified')) {
  $is_verified = ((int)($student['is_verified'] ?? 0) === 1);
} elseif (colExists($mysqli, 'studentss', 'verified')) {
  $is_verified = ((int)($student['verified'] ?? 0) === 1);
} elseif (colExists($mysqli, 'studentss', 'verification_status')) {
  $val = strtolower(trim((string)($student['verification_status'] ?? '')));
  $is_verified = in_array($val, ['verified','approved','yes','1'], true);
} elseif (colExists($mysqli, 'studentss', 'name_verified')) {
  $is_verified = ((int)($student['name_verified'] ?? 0) === 1);
}

// gender badge
$g = '';
if (colExists($mysqli, 'studentss', 'gender')) {
  $g = strtolower(trim((string)($student['gender'] ?? '')));
} elseif (colExists($mysqli, 'studentss', 'sex')) {
  $g = strtolower(trim((string)($student['sex'] ?? '')));
}
if ($g !== '') {
  $label = ($g === 'm' || $g === 'male') ? 'Male' : (($g === 'f' || $g === 'female') ? 'Female' : ucfirst($g));
  $gender_badge = ' <span class="badge bg-secondary ms-2">'.h($label).'</span>';
}

// branch (try direct column first, then branch_id -> branches table)
if (!empty($student['branch'])) {
  $branch = (string)$student['branch'];
} elseif (!empty($student['branch_name'])) {
  $branch = (string)$student['branch_name'];
} elseif (colExists($mysqli, 'studentss', 'branch_id') && tableExists($mysqli, 'branches')) {
  $bid = (int)($student['branch_id'] ?? 0);
  if ($bid > 0 && (colExists($mysqli, 'branches', 'name') || colExists($mysqli, 'branches', 'branch_name'))) {
    $nameCol = colExists($mysqli, 'branches', 'name') ? 'name' : 'branch_name';
    $stb = $mysqli->prepare("SELECT `$nameCol` AS n FROM branches WHERE id=? LIMIT 1");
    $stb->bind_param('i', $bid);
    $stb->execute();
    $r = method_exists($stb,'get_result') ? $stb->get_result()->fetch_assoc() : stmt_fetch_one_assoc($stb);
    $stb->close();
    $branch = trim((string)($r['n'] ?? '')) ?: '-';
  }
}

// ==== STUDENT ID ====
if ($student_id <= 0) { http_response_code(400); exit("Student id missing. Use ?id=123"); }

// OPTIONAL: student security
$role = $_SESSION['role'] ?? ($_SESSION['user']['role'] ?? '');
if ($role === 'student') {
  $my_id = (int)($_SESSION['user']['id'] ?? $_SESSION['student_id'] ?? 0);
  if ($my_id && $my_id !== $student_id) { http_response_code(403); exit("Forbidden."); }
}

// ==== COURSE ID (normalize) ====
$course_id = (int)($_GET['course_id'] ?? 0);

// if course_id not provided: try student_numbers latest
if ($course_id <= 0) {
  $st = $mysqli->prepare("SELECT course_id FROM student_numbers WHERE student_id=? ORDER BY id DESC LIMIT 1");
  if ($st) {
    $st->bind_param("i", $student_id);
    $st->execute();
    $row = stmt_get_one($st);
    $course_id = (int)($row['course_id'] ?? 0);
    $st->close();
  }
}


// if still missing: fallback to studentss.course_id
if ($course_id <= 0) {
  $st = $mysqli->prepare("SELECT course_id FROM studentss WHERE id=? LIMIT 1");
  if ($st) {
    $st->bind_param("i", $student_id);
    $st->execute();
    $row = stmt_get_one($st);

    $course_id = (int)($row['course_id'] ?? 0);
    $st->close();
  }
}

// If course_id is actually a batch_id, convert it
if ($course_id > 0) {
  $st = $mysqli->prepare("SELECT 1 FROM courses WHERE id=? LIMIT 1");
  $st->bind_param("i", $course_id);
  $st->execute();
  $st->store_result();
  $isCourse = ($st->num_rows > 0);
  $st->close();

  if (!$isCourse) {
    $st = $mysqli->prepare("SELECT course_id FROM batches WHERE id=? LIMIT 1");
    if ($st) {
      $st->bind_param("i", $course_id);
      $st->execute();
      $row = stmt_get_one($st);

      $mapped = (int)($row['course_id'] ?? 0);
      $st->close();
      if ($mapped > 0) $course_id = $mapped;
    }
  }
}

if ($course_id <= 0) {
  $course_id = (int)$resolved_course_id; // fallback
}


// ===== Student codes (EC / Reg / Name) =====
// Your studentss table columns: full_name, reference_no, center_reg_no, ...
// Your student_numbers columns: reference_no, reference_no2, center_reg_no, course_id, student_id, ...
function get_student_codes(mysqli $db, int $student_id, int $course_id): array {
  $st = $db->prepare("
    SELECT
      s.full_name,
      s.reference_no AS ec1,
      s.center_reg_no AS reg1,
      sn.reference_no  AS sn_ec1,
      sn.reference_no2 AS sn_ec2,
      sn.center_reg_no AS sn_reg
    FROM studentss s
    LEFT JOIN student_numbers sn
      ON sn.student_id = s.id
     AND sn.course_id  = ?
    WHERE s.id = ?
    ORDER BY sn.id DESC
    LIMIT 1
  ");
  if (!$st) {
    return [
      'full_name'    => '—',
      'ec1'          => '',
      'ec2'          => '',
      'reference_no' => '—',
      'register_no'  => '—',
    ];
  }

  $st->bind_param("ii", $course_id, $student_id);
  $st->execute();
  $row = stmt_get_one($st);

  $st->close();

  $name = (string)($row['full_name'] ?? '—');

  $ecA = trim((string)($row['sn_ec1'] ?? $row['ec1'] ?? ''));
  $ecB = trim((string)($row['sn_ec2'] ?? ''));

  $reg = trim((string)($row['sn_reg'] ?? $row['reg1'] ?? ''));

  $ecShow = $ecA !== '' ? $ecA : '—';
  if ($ecB !== '' && $ecB !== $ecA) $ecShow .= " / ".$ecB;

  return [
    'full_name'    => $name !== '' ? $name : '—',
    'ec1'          => $ecA,
    'ec2'          => $ecB,
    'reference_no' => $ecShow,
    'register_no'  => $reg !== '' ? $reg : '—',
  ];
}

// ===== Bundle-aware course_ids for modules =====
// - If selected course has modules => include it
// - Also include bundle children (if any)
function get_course_ids_for_modules(mysqli $db, int $selected_course_id): array {
  $ids = [];

  // direct modules?
  if (tableExists($db, 'course_modules')) {
    $st = $db->prepare("SELECT 1 FROM course_modules WHERE course_id=? LIMIT 1");
    if ($st) {
      $st->bind_param("i", $selected_course_id);
      $st->execute();
      $st->store_result();
      if ($st->num_rows > 0) $ids[] = $selected_course_id;
      $st->close();
    }
  }

  // children?
  if (tableExists($db, 'course_children')) {
    $st = $db->prepare("SELECT child_id FROM course_children WHERE parent_id=? ORDER BY sort_order ASC, child_id ASC");
    if ($st) {
      $st->bind_param("i", $selected_course_id);
      $st->execute();
      foreach (stmt_get_all($st) as $row) {
        $ids[] = (int)($row['child_id'] ?? 0);
      }
      $st->close();
    }
  }

  $ids = array_values(array_unique(array_filter(array_map('intval', $ids))));
  return $ids ?: [$selected_course_id];
}


/**
 * FINAL EXAMS ONLY + LAST attempt per module
 *
 * Correct mapping (based on your DB):
 *   course_modules.id  -> units.module_id
 *   units.id           -> exams.unit_id
 *   exams.id           -> results.exam_id
 *
 * IMPORTANT: results for your exam system are often matched by results.reference_no (NECxxx).
 * So we match results by:
 *   - results.student_id = $student_id   (if it matches), OR
 *   - results.reference_no IN (register_no, EC1, EC2)
 */
function get_modules_with_final_last_result(
  mysqli $db,
  int $student_id,
  array $course_ids,
  string $reg_no,
  string $ec1,
  string $ec2
): array {
  if (!$course_ids) return [];

  $course_ids = array_values(array_unique(array_map('intval', $course_ids)));
  $in = implode(',', $course_ids);

  $sql = "
    SELECT
      cm.course_id,
      c.course_name,

      cm.id    AS module_id,
      cm.title AS module_name,

      CASE
        WHEN LOWER(cm.title) LIKE '%project%' THEN 'Software Project'
        ELSE 'Online Exam'
      END AS evaluation_method,
      'Final' AS evaluation_type,

      r.date_taken AS date_evaluated,
      r.grade,

      COALESCE(
        r.status,
        CASE
          WHEN r.grade = 'P' THEN 'Pass'
          WHEN r.grade = 'F' THEN 'Fail'
          WHEN r.score IS NOT NULL AND r.total > 0 THEN
            CASE
              WHEN (r.score * 100.0 / r.total) >= COALESCE(e.pass_mark, 40) THEN 'Pass'
              ELSE 'Fail'
            END
          ELSE NULL
        END
      ) AS result

    FROM course_modules cm
    LEFT JOIN courses c ON c.id = cm.course_id

    LEFT JOIN (
      SELECT
        course_id,
        module_id,
        COALESCE(
          MAX(CASE WHEN name LIKE '%Final Exam%' THEN id END),
          MAX(CASE WHEN name LIKE '%Final%'     THEN id END)
        ) AS final_unit_id
      FROM units
      GROUP BY course_id, module_id
    ) fu
      ON fu.course_id = cm.course_id
     AND fu.module_id = cm.id

    LEFT JOIN (
      SELECT
        course_id,
        unit_id,
        COALESCE(
          MAX(CASE WHEN unit_exam LIKE '%Final Exam%' THEN id END),
          MAX(CASE WHEN title    LIKE '%Final Exam%' THEN id END),
          MAX(CASE WHEN unit_exam LIKE '%Final%'     THEN id END),
          MAX(CASE WHEN title    LIKE '%Final%'     THEN id END),
          MAX(id)
        ) AS final_exam_id
      FROM exams
      GROUP BY course_id, unit_id
    ) fe
      ON fe.course_id = cm.course_id
     AND fe.unit_id   = fu.final_unit_id

    LEFT JOIN exams e ON e.id = fe.final_exam_id

    LEFT JOIN (
      SELECT exam_id, MAX(id) AS last_result_id
      FROM results
      WHERE student_id = ?
         OR reference_no IN (?,?,?)
      GROUP BY exam_id
    ) lr ON lr.exam_id = e.id

    LEFT JOIN results r ON r.id = lr.last_result_id

    WHERE cm.course_id IN ($in)
    ORDER BY cm.course_id ASC, cm.id ASC
  ";

  try {
    $st = $db->prepare($sql);
    if (!$st) return [];

    $st->bind_param("isss", $student_id, $reg_no, $ec1, $ec2);
    $st->execute();

    $rows = stmt_get_all($st);
    $st->close();
    return $rows;
  } catch (mysqli_sql_exception $e) {
    error_log("FINAL query failed: " . $e->getMessage());
    return [];
  }
}


// ===== RUN =====
$codes = get_student_codes($mysqli, $student_id, $course_id);

$course_ids_for_modules = get_course_ids_for_modules($mysqli, $course_id);

$reg_no = ($codes['register_no'] ?? '');
$ec1    = ($codes['ec1'] ?? '');
$ec2    = ($codes['ec2'] ?? '');

$rows = get_modules_with_final_last_result($mysqli, $student_id, $course_ids_for_modules, $reg_no, $ec1, $ec2);

// Use the child-course scope for batch filtering
$course_filter_sql = '';
if (!empty($scope_child_ids) && tableExists($mysqli,'batches') && colExists($mysqli,'batches','course_id')) {
    $in = implode(',', array_map('intval', $scope_child_ids));
    $course_filter_sql = " AND b.course_id IN ($in) ";
}

// ==== BATCHES ====
$batches = [];

if (
  tableExists($mysqli,'enrollments') &&
  tableExists($mysqli,'batches') &&
  colExists($mysqli,'enrollments','batch_id')
) {
  $st = $mysqli->prepare("
  SELECT DISTINCT b.id,
         b.status,
         b.batch_code,
        $batchNameExpr AS batch_name
  FROM enrollments e
  JOIN batches b ON b.id = e.batch_id
  WHERE e.student_id = ? {$course_filter_sql}
  ORDER BY b.id ASC
");
  $st->bind_param("i", $student_id);
  $st->execute();
  $batches = stmt_fetch_all_assoc($st);
  $st->close();
}

if (!$batches && tableExists($mysqli,'student_batches') && tableExists($mysqli,'batches')) {
  $st = $mysqli->prepare("
  SELECT DISTINCT b.id,
         b.status,
         b.batch_code,
         COALESCE(NULLIF(TRIM(b.batch_name),''), 'Batch') AS batch_name
  FROM student_batches sb
  JOIN batches b ON b.id = sb.batch_id
  WHERE sb.student_id = ? {$course_filter_sql}
  ORDER BY b.id ASC
");
  $st->bind_param("i", $student_id);
  $st->execute();
  $batches = stmt_fetch_all_assoc($st);
  $st->close();
}

if (!$batches && tableExists($mysqli,'batch_students') && tableExists($mysqli,'batches')) {
  $st = $mysqli->prepare("
  SELECT DISTINCT b.id,
         b.status,
         b.batch_code,
         COALESCE(NULLIF(TRIM(b.batch_name),''), 'Batch') AS batch_name
  FROM batch_students bs
  JOIN batches b ON b.id = bs.batch_id
  WHERE bs.student_id = ? {$course_filter_sql}
  ORDER BY b.id ASC
");
  $st->bind_param("i", $student_id);
  $st->execute();
  $batches = stmt_fetch_all_assoc($st);
  $st->close();
}

// Deduplicate batches by batch_code so the same code is not shown twice
if (!empty($batches)) {
    $unique = [];
    $seen   = [];

    foreach ($batches as $row) {
        $code = strtolower(trim((string)($row['batch_code'] ?? '')));
        // fall back to id if there is no code (should be rare)
        $key  = $code !== '' ? $code : (string)((int)($row['id'] ?? 0));

        if (isset($seen[$key])) {
            continue; // skip duplicate code
        }
        $seen[$key] = true;
        $unique[]   = $row;
    }

    $batches = $unique;
}

// Use the last unique batch (for letters etc.)
$last_batch_id = null;
if (!empty($batches)) {
    $last = end($batches);
    $last_batch_id = (int)($last['id'] ?? 0);
}


// ==== Payment method label ====
$selected_method_raw = '';
if (tableExists($mysqli,'student_fee_plans')) {
  foreach (['payment_method','discount_method','pay_method','method'] as $c) {
    if (!colExists($mysqli,'student_fee_plans',$c)) continue;
    $st = $mysqli->prepare("SELECT `$c` AS m FROM student_fee_plans WHERE student_id=? ORDER BY id DESC LIMIT 1");
    $st->bind_param('i',$student_id);
    $st->execute();
    $r = method_exists($st,'get_result') ? $st->get_result()->fetch_assoc() : stmt_fetch_one_assoc($st);
    $st->close();

    $selected_method_raw = trim((string)($r['m'] ?? ''));
    if ($selected_method_raw !== '') break;
  }
}

if ($selected_method_raw === '' && tableExists($mysqli,'payments')) {
  $st = $mysqli->prepare("SELECT payment_method FROM payments WHERE student_id=? ORDER BY date_paid DESC, id DESC LIMIT 1");
  $st->bind_param('i',$student_id); $st->execute();
  $r = stmt_fetch_one_assoc($st); $st->close();
  $selected_method_raw = trim((string)($r['payment_method'] ?? ''));
}
$method_map = [
  'cash'=>'Cash','bank'=>'Bank Transfer','bank_transfer'=>'Bank Transfer','card'=>'Card',
  'card_visa'=>'Card (Visa/Master)','visa'=>'Card (Visa/Master)','master'=>'Card (Visa/Master)',
  'amex'=>'Card (Amex)','online'=>'Online','one'=>'One-time','one-time'=>'One-time','installment'=>'Installments'
];
$key = strtolower(preg_replace('/\s+/', '_', $selected_method_raw));
$selected_method = $method_map[$key] ?? ($selected_method_raw ?: '-');

// ==== Plan + installments ====
$plan = []; $installments = [];
$has_sfp = tableExists($mysqli,'student_fee_plans');
$has_ps  = tableExists($mysqli,'payment_schedule');

if ($has_sfp) {
  if ($filter_course_ids && colExists($mysqli,'student_fee_plans','course_id')) {
    $in = implode(',', array_map('intval', $filter_course_ids));
    $sql = "SELECT * FROM student_fee_plans WHERE student_id=? AND course_id IN ($in) ORDER BY id DESC LIMIT 1";
    $st  = $mysqli->prepare($sql);
    $st->bind_param("i",$student_id);
  } else {
    $st  = $mysqli->prepare("SELECT * FROM student_fee_plans WHERE student_id=? ORDER BY id DESC LIMIT 1");
    $st->bind_param("i",$student_id);
  }
  $st->execute(); $sfp = stmt_fetch_one_assoc($st); $st->close();
}

if (!empty($sfp)) {
  foreach (['promotion_plan','promo_plan','promotion','promotion_name','promo_name','discount_plan','offer_name'] as $c) {
    if (array_key_exists($c, $sfp) && trim((string)$sfp[$c]) !== '') { $promotion_plan = trim((string)$sfp[$c]); break; }
  }
}
if ($sfp) {
  $plan = [
    'id'                   => is_numeric($sfp['plan_id'] ?? '') ? (int)$sfp['plan_id'] : null,
    'plan_type'            => strtolower((string)($sfp['plan_type'] ?? '')),
    'plan_name'            => $sfp['plan_name'] ?? '',
    'course_fee_lkr'       => (float)($sfp['course_fee_lkr'] ?? 0),
    'registration_fee_lkr' => (float)($sfp['registration_fee_lkr'] ?? 0),
    'certificate_fee_usd'  => (float)($sfp['certificate_fee_usd'] ?? 0),
    'late_charges'         => (float)($sfp['late_charges'] ?? 0),
  ];
if ($has_ps) {
  $has_plan_id = colExists($mysqli,'payment_schedule','plan_id');
  $has_ps_cid  = colExists($mysqli,'payment_schedule','course_id');

  if (!empty($sfp) && $has_plan_id) {
    $st = $mysqli->prepare("
      SELECT installment_no, due_date,
             COALESCE(course_fee_lkr,0)        AS course_fee_lkr,
             COALESCE(registration_fee_lkr,0)  AS registration_fee_lkr,
             COALESCE(certificate_fee_usd,0)   AS certificate_fee_usd
        FROM payment_schedule
       WHERE plan_id=?
       ORDER BY installment_no ASC, id ASC");
    $pid = (int)$sfp['id'];
    $st->bind_param("i",$pid);
  } elseif ($has_ps_cid && $filter_course_ids) {
    $in = implode(',', array_map('intval', $filter_course_ids));
    $st = $mysqli->prepare("
      SELECT installment_no, due_date,
             COALESCE(course_fee_lkr,0)        AS course_fee_lkr,
             COALESCE(registration_fee_lkr,0)  AS registration_fee_lkr,
             COALESCE(certificate_fee_usd,0)   AS certificate_fee_usd
        FROM payment_schedule
       WHERE student_id=? AND course_id IN ($in)
       ORDER BY installment_no ASC, id ASC");
    $st->bind_param("i",$student_id);
  } else {
    $st = $mysqli->prepare("
      SELECT installment_no, due_date,
             COALESCE(course_fee_lkr,0)        AS course_fee_lkr,
             COALESCE(registration_fee_lkr,0)  AS registration_fee_lkr,
             COALESCE(certificate_fee_usd,0)   AS certificate_fee_usd
        FROM payment_schedule
       WHERE student_id=?
       ORDER BY installment_no ASC, id ASC");
    $st->bind_param("i",$student_id);
  }

  $st->execute(); $installments = stmt_fetch_all_assoc($st); $st->close();
}

} else {
  if ($resolved_course_id>0 && tableExists($mysqli,'payment_plans')) {
    $st = $mysqli->prepare("SELECT * FROM payment_plans WHERE course_id=? AND (status='Active' OR status IS NULL) ORDER BY id ASC LIMIT 1");
    $st->bind_param("i",$resolved_course_id); $st->execute();
    $plan = stmt_fetch_one_assoc($st); $st->close();
    if (!empty($plan['id']) && tableExists($mysqli,'installments')) {
      $st = $mysqli->prepare("
        SELECT installment_no, due_date, course_fee_lkr, registration_fee_lkr, certificate_fee_usd
          FROM installments
         WHERE plan_id=?
         ORDER BY installment_no ASC, id ASC");
      $st->bind_param("i",$plan['id']); $st->execute();
      $installments = stmt_fetch_all_assoc($st); $st->close();
    }
  }
}

$sumC=0.0; $sumR=0.0; $sumU=0.0;
foreach ($installments as $ins) { $sumC+=(float)($ins['course_fee_lkr']??0); $sumR+=(float)($ins['registration_fee_lkr']??0); $sumU+=(float)($ins['certificate_fee_usd']??0); }

$course_fee_lkr = (float)($plan['course_fee_lkr'] ?? 0);
$reg_fee_lkr    = (float)($plan['registration_fee_lkr'] ?? 0);
$cert_fee_usd   = (float)($plan['certificate_fee_usd'] ?? 0);
$late_charges   = (float)($plan['late_charges'] ?? 0);
$extra_fee_lkr = 0.0;
if (isset($sfp['extra_fee_lkr'])) {
  $extra_fee_lkr = (float)$sfp['extra_fee_lkr'];
}

$ptype = strtolower((string)($plan['plan_type'] ?? ''));

if ($ptype === 'installment' || $ptype === 'inst'
 || (($course_fee_lkr + $reg_fee_lkr + $cert_fee_usd) <= 0 && ($sumC + $sumR + $sumU) > 0)) {
  $course_fee_lkr = $sumC; $reg_fee_lkr = $sumR; $cert_fee_usd = max($cert_fee_usd, $sumU);
}

$discount_lkr = 0.0;
if (!empty($sfp)) {
  $discount_lkr += (float)($sfp['plan_discount_lkr']   ?? 0);
  $discount_lkr += (float)($sfp['manual_discount_lkr'] ?? 0);
  $discount_lkr += (float)($sfp['method_discount_lkr'] ?? 0);
} else if (tableExists($mysqli,'student_fee_plans')) {
  foreach (['discount_lkr','discount_amount_lkr','discount_amount'] as $c) {
    if (!colExists($mysqli,'student_fee_plans',$c)) continue;
    $st = $mysqli->prepare("SELECT `$c` AS d FROM student_fee_plans WHERE student_id=? ORDER BY id DESC LIMIT 1");
    $st->bind_param("i",$student_id); $st->execute();
    $r = stmt_fetch_one_assoc($st); $st->close();
    $discount_lkr = (float)($r['d'] ?? 0);
    break;
  }
}

$already_paid_lkr = $already_paid_lkr ?? 0.0;
$paid_uka         = $paid_uka ?? 0.0;
$sub_total_lkr     = $course_fee_lkr + $reg_fee_lkr;
$total_payable_lkr = max(0, $sub_total_lkr - max(0,$discount_lkr) + $late_charges + $extra_fee_lkr);
$outstanding_lkr   = max(0, $total_payable_lkr - $already_paid_lkr);

// payments history + paid totals
$payments = []; $already_paid_lkr = 0.0; $paid_uka = 0.0;
if (tableExists($mysqli,'payments')) {
  $st = $mysqli->prepare("SELECT * FROM payments WHERE student_id=? ORDER BY date_paid DESC, id DESC");
  $st->bind_param("i",$student_id); $st->execute();
  $payments = stmt_fetch_all_assoc($st); $st->close();
  foreach ($payments as $row) { $already_paid_lkr += (float)$row['amount']; if (!empty($row['usd_amount'])) $paid_uka += (float)$row['usd_amount']; }
}
$outstanding_lkr = max(0, $total_payable_lkr - $already_paid_lkr);

// verification / checklist
$ver = [];
if (tableExists($mysqli,'student_verifications')) {
  $st = $mysqli->prepare("SELECT * FROM student_verifications WHERE student_id=? LIMIT 1");
  $st->bind_param("i",$student_id); $st->execute();
  $ver = stmt_fetch_one_assoc($st); $st->close();
}
$is_verified = !empty($ver) && (int)($ver['verified'] ?? 0) === 1;

$chk_completed = 0; $chk_total = 6;
if (tableExists($mysqli,'student_checklist')) {
  $st = $mysqli->prepare("SELECT COUNT(*) AS c FROM student_checklist WHERE student_id=? AND is_done=1");
  $st->bind_param("i",$student_id); $st->execute();
  $tmp = stmt_fetch_one_assoc($st); $st->close();
  $chk_completed = (int)($tmp['c'] ?? 0);
}

// pretty fields
$reg_id_display = str_pad((string)$student_id, 8, '0', STR_PAD_LEFT);
$created_at = $student['created_at'] ?? '';
$expiry = '';
if ($created_at) { $dt=new DateTime($created_at); $dt->modify('+1 year'); $expiry=$dt->format('Y-m-d'); }
$gender_badge = !empty($student['gender']) ? (' <span class="badge bg-dark-subtle text-dark">'.h($student['gender']).'</span>') : '';

// branch (robust)
$branch = '-';
if (!empty($student['branch_name'])) $branch = trim((string)$student['branch_name']);
elseif (!empty($student['branch']))  $branch = trim((string)$student['branch']);
elseif (!empty($student['branch_id']) && (int)$student['branch_id'] > 0 && tableExists($mysqli,'branches')) {
  $st = $mysqli->prepare("SELECT name FROM branches WHERE id=? LIMIT 1");
  $bid = (int)$student['branch_id'];
  $st->bind_param('i', $bid); $st->execute();
  $r = stmt_fetch_one_assoc($st); $st->close();
  if (!empty($r['name'])) $branch = (string)$r['name'];
} elseif (tableExists($mysqli,'enrollments') && tableExists($mysqli,'batches') && tableExists($mysqli,'branches') && colExists($mysqli,'batches','branch_id')) {
  $st = $mysqli->prepare("
    SELECT DISTINCT br.name
      FROM enrollments e
      JOIN batches b  ON b.id  = e.batch_id
      JOIN branches br ON br.id = b.branch_id
     WHERE e.student_id = ?
     ORDER BY br.name ASC");
  $st->bind_param('i', $student_id);
  $st->execute();
  $names = [];
  if (method_exists($st,'get_result')) {
    $rs = $st->get_result();
    while ($row = $rs->fetch_assoc()) { $nm = trim((string)($row['name'] ?? '')); if ($nm !== '') $names[] = $nm; }
  } else {
    $rows = stmt_fetch_all_assoc($st);
    foreach ($rows as $row) { $nm = trim((string)($row['name'] ?? '')); if ($nm !== '') $names[] = $nm; }
  }
  $st->close();
  if ($names) { $branch = $names[0]; if (count($names) > 1) { $branch .= ' (+' . (count($names)-1) . ')'; } }
}

/* === Course context for this view (only what we should show) === */
$context_course_ids = [];
$target_course_id = $course_id > 0 ? $course_id : $resolved_course_id;

if ($target_course_id > 0) {
  // If it's a bundle parent, use its children; else use itself
  if (tableExists($mysqli,'course_children')) {
    $st = $mysqli->prepare("SELECT child_id FROM course_children WHERE parent_id=?");
    $st->bind_param('i', $target_course_id);
    $st->execute();
    $rows = stmt_fetch_all_assoc($st);
    $st->close();
    foreach ($rows as $r) $context_course_ids[] = (int)$r['child_id'];
  }
  if (!$context_course_ids) $context_course_ids = [$target_course_id];
}

// reference display — only for selected course; bundle parent => children
$__refs = [];
if ($scope_child_ids) {
  // if a child has no row in student_numbers, fallback to its parent
  $parent_of = [];
  if (tableExists($mysqli,'course_children')) {
    $in = implode(',', array_map('intval',$scope_child_ids));
    if ($in) {
      $rs = $mysqli->query("SELECT child_id, parent_id FROM course_children WHERE child_id IN ($in)");
      if ($rs) { while ($r = $rs->fetch_assoc()) $parent_of[(int)$r['child_id']] = (int)$r['parent_id']; $rs->free(); }
    }
  }

  foreach ($scope_child_ids as $cid) {
    $refRow = $refs_by_course[$cid] ?? null;
    if (!$refRow && isset($parent_of[$cid])) $refRow = $refs_by_course[$parent_of[$cid]] ?? null;

    if ($refRow) {
      $ec1 = trim((string)($refRow['ec1'] ?? ''));
      $ec2 = trim((string)($refRow['ec2'] ?? ''));
      if ($ec1 !== '') $__refs[] = $ec1;
      if ($ec2 !== '') $__refs[] = $ec2;
    }
  }
}
$__refs = array_values(array_unique(array_filter($__refs)));

// final display value (fallback to legacy single fields only if nothing was found)
$ref_display = $__refs ? implode('/', $__refs) : ($reference_no ?: ($ver['student_ref_no'] ?? '-'));

// always include resolved course as a safety
if (!empty($resolved_course_id)) $enrolled_course_ids[] = (int)$resolved_course_id;
$enrolled_course_ids = array_values(array_unique(array_filter($enrolled_course_ids)));

// 2) map parents ↔ children (for bundle fallback to parent course_id rows in student_numbers)
$children_of = [];   // parent_id => [child_id...]
$parent_of   = [];   // child_id => parent_id
if ($enrolled_course_ids && tableExists($mysqli, 'course_children')) {
  // pull only mappings that involve enrolled parents
  $in = implode(',', array_map('intval', $enrolled_course_ids));
  $sql = "SELECT parent_id, child_id FROM course_children"
       . ($in ? " WHERE parent_id IN ($in)" : "");
  $rs = $mysqli->query($sql);
  if ($rs) {
    while ($row = $rs->fetch_assoc()) {
      $p = (int)$row['parent_id']; $c = (int)$row['child_id'];
      $children_of[$p][] = $c;
      $parent_of[$c] = $p;
    }
    $rs->free();
  }
}

// 3) expand courses to “all ids we should show ECs for”
$all_course_ids_for_refs = [];
foreach ($enrolled_course_ids as $cid0) {
  if (!empty($children_of[$cid0])) {
    // bundle → show ECs for each child
    $all_course_ids_for_refs = array_merge($all_course_ids_for_refs, $children_of[$cid0]);
  } else {
    // single course
    $all_course_ids_for_refs[] = $cid0;
  }
}
$all_course_ids_for_refs = array_values(array_unique($all_course_ids_for_refs));

// 4) build the EC list from student_numbers: prefer child row; else fall back to parent row
/* === Reference No (only selected course or its children if bundle) === */
$__refs = [];
foreach ($context_course_ids as $cid) {
  $r = $refs_by_course[$cid] ?? null;
  if ($r) {
    $ec1 = trim((string)($r['ec1'] ?? ''));
    $ec2 = trim((string)($r['ec2'] ?? ''));
    if ($ec1 !== '') $__refs[] = $ec1;
    if ($ec2 !== '') $__refs[] = $ec2;
  } else {
    // Optional fallback: if this child has no EC, try its parent’s EC once
    if (tableExists($mysqli,'course_children')) {
      $st = $mysqli->prepare("SELECT parent_id FROM course_children WHERE child_id=? LIMIT 1");
      $st->bind_param('i',$cid); $st->execute();
      $p = stmt_fetch_one_assoc($st); $st->close();
      if ($p) {
        $rp = $refs_by_course[(int)$p['parent_id']] ?? null;
        if ($rp) {
          $ec1 = trim((string)($rp['ec1'] ?? ''));
          $ec2 = trim((string)($rp['ec2'] ?? ''));
          if ($ec1 !== '') $__refs[] = $ec1;
          if ($ec2 !== '') $__refs[] = $ec2;
        }
      }
    }
  }
}
$__refs = array_values(array_unique(array_filter($__refs)));
if ($__refs) {
  usort($__refs, function($a,$b){
    $na = (int)preg_replace('/\D+/', '', $a); $nb = (int)preg_replace('/\D+/', '', $b);
    return ($na <=> $nb) ?: strcmp($a,$b);
  });
  $ref_display = implode('/', $__refs);
} else {
  // only if nothing was found for the course context
  $ref_display = $reference_no ?: ($ver['student_ref_no'] ?? '-');
}


$payment_status_badge = $outstanding_lkr > 0 ? '<span class="badge bg-danger">Overdue</span>' : '<span class="badge bg-success">Paid</span>';

$already_paid_lkr = 0.0;
$paid_uka         = 0.0;
// Add Payment modal data-attrs precompute (allocation-safe)
$paid_course=0.0; $paid_reg_lkr=0.0; $paid_uka=0.0;
$has_fee_types_col = tableExists($mysqli,'payments') && (colExists($mysqli,'payments','fee_type') || colExists($mysqli,'payments','items_json')) ? 1 : 0;
if (tableExists($mysqli,'payments')) {
  $cols = ['id','amount'];
  $has_pay_usd   = colExists($mysqli,'payments','usd_amount');
  $has_pay_ftype = colExists($mysqli,'payments','fee_type');
  $has_pay_items = colExists($mysqli,'payments','items_json');
  $has_pay_curr  = colExists($mysqli,'payments','currency');
  if ($has_pay_usd)   $cols[] = 'usd_amount';
  if ($has_pay_ftype) $cols[] = 'fee_type';
  if ($has_pay_items) $cols[] = 'items_json';
  if ($has_pay_curr)  $cols[] = 'currency';
  $sql = "SELECT ".implode(',', $cols)." FROM payments WHERE student_id=? ORDER BY date_paid ASC, id ASC";
  $st = $mysqli->prepare($sql); $st->bind_param('i',$student_id); $st->execute();
  $rows = stmt_fetch_all_assoc($st); $st->close();

  $course_due_after_discount = max(0.0, (float)$course_fee_lkr - max(0.0,(float)$discount_lkr));
  $rem_course = $course_due_after_discount; $rem_reg=(float)$reg_fee_lkr;
  foreach ($rows as $p) {
    $amtL = (float)($p['amount'] ?? 0); $amtU = (float)($p['usd_amount'] ?? 0);
    $ft   = strtolower(trim((string)($p['fee_type'] ?? '')));
    $cur  = strtoupper(trim((string)($p['currency'] ?? '')));
    if ($amtU > 0 || $cur === 'USD') $paid_uka += ($amtU > 0) ? $amtU : 0.0;

    $j = json_decode((string)($p['items_json'] ?? ''), true);
    if (is_array($j) && isset($j['items']) && is_array($j['items'])) {
      foreach ($j['items'] as $it) {
        $type = strtolower(trim((string)($it['type'] ?? '')));
        $ccy  = strtoupper(trim((string)($it['currency'] ?? 'LKR')));
        $a    = (float)($it['amount'] ?? 0);
        if ($ccy === 'USD' && $type === 'uk awards fee') { $paid_uka     += $a; }
        if ($ccy === 'LKR' && $type === 'course fee')    { $paid_course  += $a; }
        if ($ccy === 'LKR' && $type === 'registration fee'){ $paid_reg_lkr += $a; }
      }
      continue;
    }
    if ($ft === 'course fee' || $ft === 'course_fee') { $paid_course += $amtL; continue; }
    if ($ft === 'registration fee' || $ft === 'registration_fee' || $ft === 'reg_fee') { $paid_reg_lkr += $amtL; continue; }
    if ($ft === 'uk awards fee' || $ft === 'uk_awards') { if ($amtU > 0) $paid_uka += $amtU; continue; }
    // fallback allocation
    if ($amtL > 0) {
      $take_course = min($amtL, max(0.0, $rem_course - $paid_course));
      if ($take_course > 0) { $paid_course += $take_course; $amtL -= $take_course; }
      if ($amtL > 0) {
        $take_reg = min($amtL, max(0.0, $rem_reg - $paid_reg_lkr));
        if ($take_reg > 0) { $paid_reg_lkr += $take_reg; $amtL -= $take_reg; }
      }
    }
  }
}
$__course_total   = number_format((float)$course_fee_lkr, 2, '.', '');
$__course_paid    = number_format((float)$paid_course,     2, '.', '');
$__uka_total      = number_format((float)$cert_fee_usd,    2, '.', '');
$__uka_paid       = number_format((float)$paid_uka,        2, '.', '');
$__has_fee_types  = (string)$has_fee_types_col;
$__out_lkr        = number_format((float)$outstanding_lkr, 2, '.', '');
$SID = (int)$student_id;
$customModalId = 'customPlanModal-' . $SID;

function ec_get_student_batches(mysqli $db, int $studentId): array {
  if (!tableExists($db, 'enrollments') || !tableExists($db, 'batches')) return [];

  $sql = "
    SELECT
      e.id AS enrollment_id,
      e.batch_id,
      b.batch_code,
      b.status
    FROM enrollments e
    INNER JOIN batches b ON b.id = e.batch_id
    WHERE e.student_id = ?
    ORDER BY b.batch_code
  ";

  $st = $db->prepare($sql);
  if (!$st) return [];
  $st->bind_param('i', $studentId);
  $st->execute();

  $rows = stmt_get_all($st);   // <-- IMPORTANT
  $st->close();
  return $rows;
}

function esc($s){ return h($s); }
function nf($n,$d=2){ return number_format((float)$n,$d); }
?>

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Evaluation Attempts</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    .card-title-row{display:flex;align-items:center;justify-content:space-between;}
    .small-muted{font-size:.9rem;color:#6c757d;}
    .table thead th{white-space:nowrap;}
    
  /* Compact layout scoped to #actionModal */
    #actionModal .modal-body, #actionModal .modal-body *{font-size:.85rem}
    #actionModal .container.mt-3{margin-top:0!important}
    #actionModal .nav-tabs{margin-top:.25rem;margin-bottom:.35rem}
    #actionModal .card{margin-bottom:.35rem}
    #actionModal .card.shadow-sm.mb-3{margin-bottom:.35rem!important}
    #actionModal .card-body{padding:.5rem .6rem}
    #actionModal .card-header, #actionModal .ps-head{padding:.4rem .6rem}
    #actionModal h4{font-size:1rem;margin:0}
    #actionModal .table>:not(caption)>*>*{padding:.35rem .45rem}
    #actionModal .kv-row{display:flex;gap:10px;align-items:center;margin:.2rem 0}
    #actionModal .kv-row .k{min-width:150px;color:#6c757d}
    #actionModal .kv-row .v{font-weight:500}
    #actionModal .kv-group{background:#fff;border:1px solid #e9ecef;border-radius:.45rem;padding:.75rem}
    #actionModal .kv-title{font-weight:600;margin-bottom:.35rem}
    #actionModal .overview-banner{background:#fff3cd;border:1px solid #ffe69c;border-radius:.35rem;padding:8px 12px}
    #actionModal .letter-card{display:block;border:1px solid #e9ecef;border-radius:.45rem;padding:10px 12px;text-decoration:none;background:#fff;color:#0d6efd;min-height:90px}
    #actionModal .letter-card .lc-head{font-weight:700;font-size:.9rem;text-transform:uppercase}
    #actionModal .letter-card .lc-points{margin:.35rem 0 0;padding-left:0;list-style:none}
    #actionModal .letter-card .lc-points li{font-size:.8rem;margin:.1rem 0}
    #actionModal .ps-card{background:#fff;border:1px solid #e9ecef;border-radius:.45rem}
    #actionModal .ps-table th,#actionModal .ps-table td{vertical-align:middle;padding:.35rem .45rem}
    #actionModal .big-stat{font-size:1.4rem;font-weight:700}
    #actionModal .big-stat-wrap{display:flex;justify-content:center;align-items:center;height:100%;padding:12px 0}
    #actionModal .bundle-chip{border-radius:999px;padding:.2rem .6rem}
    #actionModal .modal-header{ padding:.50rem .75rem !important; }
    #actionModal .modal-header .modal-title{ font-size:1rem !important; line-height:1.1 !important; margin:0 !important; font-weight:700; }
    #actionModal .btn-close{ transform:scale(.9); }
    #actionModal .modal-body{ padding-top:.5rem !important; }
    #actionModal .modal-header + .modal-body > *:first-child{ margin-top:0 !important; }
    #actionModal .container.mt-3{ margin-top:.2rem !important; }
    #actionModal .card.shadow-sm.mb-3{ margin-bottom:.35rem !important; }
    #actionModal .card.shadow-sm.mb-3 .card-body{ padding:.45rem .6rem !important; }
    #actionModal .card.shadow-sm.mb-3 h4{ font-size:1rem !important; margin:0 !important; }
    #actionModal .nav-tabs{ margin:.25rem 0 .35rem !important; }
    #actionModal .table>:not(caption)>*>*{ padding:.35rem .45rem !important; }
    #customPlanModal .modal-dialog { margin-top:.25rem; }
    /* left-aligned everything inside modal */
    #actionModal .modal-body, #actionModal .modal-body .card, #actionModal .modal-body .card-header,
    #actionModal .modal-body .card-body, #actionModal .modal-body .tab-pane, #actionModal .modal-body .row,
    #actionModal .modal-body .col, #actionModal .modal-body .kv-group, #actionModal .modal-body .kv-row .k,
    #actionModal .modal-body .kv-row .v, #actionModal .modal-body table, #actionModal .modal-body table td,
    #actionModal .modal-body table th, #actionModal .modal-body .form-check, #actionModal .modal-body .form-check-label {
      text-align:left !important;
    }
  </style>

</head>
  <!-- Tabs -->
  <ul class="nav nav-tabs" id="studentTabs" role="tablist">
    <li class="nav-item"><a class="nav-link active" data-bs-toggle="tab" href="#overview">Overview</a></li>
    <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#course">Course Info</a></li>
    <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#payments">Payments</a></li>
    <li class="nav-item"><a class="nav-link" data-bs-toggle="tab" href="#other">Other</a></li>
  </ul>
  <div class="tab-content mt-3">

    <!-- OVERVIEW -->
<div class="tab-pane fade show active" id="overview">
  <?php if (!$is_verified): ?>
  <div class="overview-banner mb-3">
    <div class="fw-semibold mb-1">Incomplete Registration</div>
    <div class="ovr-hint mb-2">The registration process has been interrupted because of the following reason(s).</div>
    <div class="d-flex align-items-center gap-2">
      <i class="bi bi-exclamation-triangle-fill text-warning"></i>
      <span>Unverified Registration. Name verification has to be done</span>
      <a href="#" id="goVerify" class="ms-2 fw-semibold">Verify</a>
    </div>
  </div>
  <?php endif; ?>

  <div class="row g-3">
    <!-- Left -->
    <div class="col-lg-6">
      <div class="kv-group">
        <div class="kv-title"><i class="bi bi-info-circle me-1"></i>Details</div>

        <div class="kv-row">
          <div class="k">Registration Status</div>
          <div class="v">
            <?= $is_verified
              ? '<span class="badge bg-success">Verified</span>'
              : '<span class="badge bg-warning text-dark">Pending Verification</span>' ?>
          </div>
        </div>

        <div class="kv-row"><div class="k">Student ID</div><div class="v"><?= h($center_reg_no ?: '-') ?></div></div>

        <div class="kv-row"><div class="k">Student Name</div><div class="v"><?= h($student['full_name'] ?? '-') ?><?= $gender_badge ?></div></div>

        <div class="kv-row">
          <div class="k">Course</div>
          <div class="v">
            <?= h($course['course_name'] ?? $course['name'] ?? '-') ?><br>
            <small class="text-muted"><?= h($course['description'] ?? '') ?></small>
          </div>
        </div>

        <div class="kv-row"><div class="k">Branch Enrolled</div><div class="v"><?= h($branch ?: '-') ?></div></div>

        <!-- Batch(es) — show ONLY the batch_code -->
        <div class="kv-row">
          <div class="k">Batch(es)</div>
            <div class="v">
   <?php
      // numeric PK from studentss table
      $studentDbId     = (int)($student['id'] ?? 0);
      $studentBatches  = ec_get_student_batches($mysqli, $studentDbId);
    ?>

    <?php if (!empty($studentBatches)): ?>
      <?php foreach ($studentBatches as $b): ?>
        <?php $code = trim((string)($b['batch_code'] ?? '')); ?>
        <div>
          <?= $code !== '' ? h($code) : '—' ?>
          <?php if (!empty($b['status']) && strtolower((string)$b['status']) === 'active'): ?>
            <i class="bi bi-check-circle-fill text-success ms-1"></i>
          <?php endif; ?>
        </div>
      <?php endforeach; ?>
    <?php else: ?>
      —
    <?php endif; ?>
  </div>

        </div>
        <!-- /Batch(es) -->
      </div>
    </div>

        <!-- Right -->
        <div class="col-lg-6">
          <div class="kv-group">
            <div class="kv-title"><i class="bi bi-clipboard-data me-1"></i>Registration</div>
            <div class="kv-row"><div class="k">Payment Status</div><div class="v"><?= $payment_status_badge ?></div></div>
            <div class="kv-row"><div class="k">Registration ID</div><div class="v"><?= h($reg_id_display) ?></div></div>
            <div class="kv-row"><div class="k">Reference No</div><div class="v"><?= h($ref_display) ?></div></div>
            <div class="kv-row"><div class="k">Date Registered</div><div class="v"><?= h($created_at ?: '-') ?></div></div>
            <div class="kv-row"><div class="k">Date Expiry</div><div class="v"><?= h($expiry ?: '-') ?></div></div>
            <div class="kv-row"><div class="k">Checklist</div><div class="v"><?= (int)$chk_completed ?> / <?= (int)$chk_total ?> Completed</div></div>
          </div>
        </div>
      </div>

      <!-- Payment Summary + Accumulated Dues -->
      <div class="row g-3 mt-1">
        <div class="col-lg-8">
          <div class="ps-card">
            <div class="ps-head"><h6 class="fw-bold m-0"><i class="bi bi-table me-1"></i>Payment Summary</h6></div>
            <div class="ps-body">
              <table class="table table-bordered m-0 ps-table text-center">
                <thead class="table-light">
                  <tr>
                    <th style="width:80px"></th>
                    <th>Total Payable</th>
                    <th>Already Paid Total</th>
                    <th>Total Outstanding</th>
                  </tr>
                </thead>
                <tbody>
                  <tr>
                    <th>LKR</th>
                    <td><?= nf($total_payable_lkr) ?></td>
                    <td><?= nf($already_paid_lkr) ?></td>
                    <td><?= nf($outstanding_lkr) ?></td>
                  </tr>
                  <tr>
                    <th>USD</th>
                    <td><?= nf($cert_fee_usd) ?></td>
                    <td><?= nf($paid_uka) ?></td>
                    <td><?= nf(max(0, $cert_fee_usd - $paid_uka)) ?></td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>

        <div class="col-lg-4">
          <div class="ps-card h-100">
            <div class="ps-head"><h6 class="fw-bold m-0"><i class="bi bi-graph-up-arrow me-1"></i>Accumulated Dues</h6></div>
            <div class="big-stat-wrap">
              <div class="text-center">
                <div class="big-stat text-danger"><?= nf($outstanding_lkr) ?></div>
                <div class="ovr-hint">LKR</div>
                <div class="mt-2 text-muted"><?= nf(max(0, $cert_fee_usd - $paid_uka)) ?> USD</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div><!-- /overview -->
    
    <!-- COURSE INFO -->
<div class="tab-pane fade" id="course">

  <!-- Course Details -->
  <div class="card mb-3">
    <div class="card-header"><h6 class="fw-bold m-0">Course Details</h6></div>
    <div class="card-body">
      <table class="table table-bordered mb-0">
        <tr><th style="width:220px">Name</th><td><?= h($course['course_name'] ?? $course['name'] ?? '-') ?></td></tr>
        <tr><th>Duration</th><td><?= h($course['duration'] ?? '-') ?><?= isset($course['duration']) ? ' months' : '' ?></td></tr>
        <tr><th>Description</th><td><?= h($course['description'] ?? $course['course_description'] ?? '-') ?></td></tr>
      </table>
    </div>
  </div>

  <!-- Bundle chips -->
  <?php if (!empty($bundle_children)): ?>
    <div class="mb-3">
      <?php foreach ($bundle_children as $i => $bc):
        $cid = (int)$bc['id'];
        $r   = $refs_by_course[$cid] ?? null;
        $ecA = $r['ec1'] ?? '';
        $ecB = $r['ec2'] ?? '';
        $ecLabel = trim($ecA . ($ecA && $ecB ? ' / ' : '') . $ecB);
      ?>
        <button type="button"
                class="btn btn-sm <?= $i===0 ? 'btn-primary' : 'btn-outline-primary' ?> me-2 mb-2 bundle-chip"
                data-cid="<?= $cid ?>">
          <?= h($bc['label'] ?? ($bc['course_name'] ?? ($bc['name'] ?? 'Course'))) ?>
          <?php if ($ecLabel !== ''): ?>
            <span class="badge bg-light text-dark ms-2"><?= h($ecLabel) ?></span>
          <?php endif; ?>
        </button>
      <?php endforeach; ?>
    </div>
  <?php endif; ?>

  <!-- Bundle blocks -->
  <?php foreach ($bundle_children as $i => $bc): $cid = (int)$bc['id']; ?>
    <div class="bundle-block <?= $i===0 ? '' : 'd-none' ?>" data-cid="<?= $cid ?>">

      <!-- Lesson Plan -->
      <div class="card mb-3">
        <div class="card-header"><h6 class="fw-bold m-0">Lesson Plan</h6></div>
        <div class="card-body p-0">
          <table class="table m-0">
            <thead class="table-light">
              <tr><th style="width:60px">#</th><th>Lesson Title</th></tr>
            </thead>
            <tbody>
              <?php $titles = $child_lessons[$cid] ?? []; ?>
              <?php if (!empty($titles)): ?>
                <?php foreach ($titles as $idx => $title): ?>
                  <tr><td><?= $idx+1 ?></td><td><?= h($title) ?></td></tr>
                <?php endforeach; ?>
              <?php else: ?>
                <tr><td colspan="2" class="text-center">No lessons added.</td></tr>
              <?php endif; ?>
            </tbody>
          </table>
        </div>
      </div>
      
      
<body class="bg-light">
<div class="container py-4">
  <div class="card shadow-sm">
    <div class="card-header bg-white">
      <div class="card-title-row">
        <div class="fw-semibold"><span class="me-2">▦</span> Evaluation Attempts</div>
        <div><span class="text-secondary">⌃</span></div>
      </div>
    </div>

    <div class="card-body">

      <div class="mb-3 p-3 rounded bg-white border">
        <div class="fw-semibold"><?= h($codes['full_name']) ?></div>
        <div class="text-muted small">
          EC No: <b><?= h($codes['reference_no']) ?></b>
          &nbsp; | &nbsp;
          Reg No: <b><?= h($codes['register_no']) ?></b>
        </div>
      </div>

      <div class="mb-2 fw-semibold small-muted">FINAL EXAMS (Last Attempt)</div>

      <div class="table-responsive mb-2">
        <table class="table table-bordered align-middle">
          <thead class="table-light">
            <tr>
              <th style="min-width:320px;">Module</th>
              <th style="min-width:180px;">Evaluation Method</th>
              <th style="min-width:90px;">Type</th>
              <th style="min-width:140px;">Date Evaluated</th>
              <th style="min-width:90px;">Grade</th>
              <th style="min-width:90px;">Result</th>
            </tr>
          </thead>
          <tbody>
            <?php if (!$rows): ?>
              <tr><td colspan="6" class="text-center text-muted">No modules found.</td></tr>
            <?php else: ?>
              <?php foreach ($rows as $r): ?>
                <tr>
                  <td><?= h($r['module_name'] ?? '-') ?></td>
                  <td><?= h($r['evaluation_method'] ?? '-') ?></td>
                  <td><?= h($r['evaluation_type'] ?? 'Final') ?></td>
                  <td><?= !empty($r['date_evaluated']) ? h($r['date_evaluated']) : '-' ?></td>
                  <td><?= !empty($r['grade']) ? h($r['grade']) : '-' ?></td>
                  <td><?= !empty($r['result']) ? h($r['result']) : '-' ?></td>
                </tr>
              <?php endforeach; ?>
            <?php endif; ?>
          </tbody>
        </table>
      </div>

    </div>
  </div>
</div>

</body>
</html>
