<?php
// new_registration.php
require_once __DIR__ . '/../includes/auth.php';
ec_require_login();                   // call AFTER requiring auth.php

$db = ec_db();
if (!$db) { die('DB Error: connection failed'); }
$conn = $db;
$conn->set_charset('utf8mb4');


// --- resolve branch from the logged-in user (to post with the form) ---
$reg_branch_id = null; 
$reg_branch_name = null;

$uid = (int)($_SESSION['user']['id'] ?? 0);
if ($uid > 0) {
  $st = $conn->prepare("SELECT branch_id, branch_name FROM users WHERE id=? LIMIT 1");
  $st->bind_param('i', $uid);
  $st->execute();
  if ($r = $st->get_result()->fetch_assoc()) {
    $reg_branch_id   = $r['branch_id']   ?? null;
    $reg_branch_name = $r['branch_name'] ?? null;
  }
  $st->close();
}


// example for the create/insert code
//$createdBy = (int)($_SESSION['user_id'] ?? 0);
//$sql = "INSERT INTO studentss (full_name, course_id, center_reg_no, created_at, created_by)
//        VALUES (?,?,?,?,?)";
//$st  = $conn->prepare($sql);
//$st->bind_param('siisi', $full_name, $course_id, $center_reg_no, $created_at, $createdBy);
//$st->execute();


/* ---------- Helper: course image url or inline placeholder ---------- */
function course_img_url($id, $code = '') {
    $code = trim($code ?? '');
    $doc = rtrim($_SERVER['DOCUMENT_ROOT'] ?? '', "/\\");
    $candidates = [
        "/EDENrms/uploads/courses/{$id}.jpg",
        "/EDENrms/uploads/courses/{$id}.png",
        "/EDENrms/uploads/courses/{$code}.jpg",
        "/EDENrms/uploads/courses/{$code}.png",
        "/EDENrms/assets/img/courses/{$id}.jpg",
        "/EDENrms/assets/img/courses/{$id}.png",
        "/EDENrms/assets/img/courses/{$code}.jpg",
        "/EDENrms/assets/img/courses/{$code}.png",
    ];
    foreach ($candidates as $web) {
        if ($web && strpos($web, "{$code}.") !== false && $code === "") continue;
        $fs = $doc . str_replace("/", DIRECTORY_SEPARATOR, $web);
        if ($doc && is_file($fs)) return $web;
    }
    $label = $code !== "" ? htmlspecialchars($code) : "COURSE";
    $svg = '<svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72">'
         . '<rect width="72" height="72" fill="#f1f3f5"/>'
         . '<text x="36" y="39" text-anchor="middle" font-family="Arial,Helvetica,sans-serif" '
         . 'font-size="12" fill="#adb5bd">'.$label.'</text></svg>';
    return "data:image/svg+xml;utf8," . rawurlencode($svg);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
   
<meta charset="UTF-8" />
<title>New Registration</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>

<style>
  body{background:#f5f6f8}
  .step{display:none}
  .step.active{display:block}
  .progressbar{display:flex;gap:6px;list-style:none;padding:0;margin:0 0 18px 0}
  .progressbar li{flex:1;text-align:center;font-weight:600;color:#6c757d;position:relative}
  .progressbar li:before{content:"";display:block;height:6px;background:#dee2e6;border-radius:999px;margin:0 8px 8px}
  .progressbar li.active{color:#198754}
  .progressbar li.active:before{background:#198754}
  .form-section{padding:14px;border:1px solid #e9ecef;border-radius:.5rem;background:#fff}
  .mini-hint{font-size:.85rem;color:#6c757d}
  .search-results{position:absolute;z-index:20;background:#fff;border:1px solid #e9ecef;border-radius:.5rem;max-height:260px;overflow:auto;width:100%}
  .search-results div{padding:8px 10px;cursor:pointer}
  .search-results div:hover{background:#f1f3f5}
  .table-tight td,.table-tight th{padding:.45rem .5rem}

  /* Course cards */
  .course-card{border:1px solid #e9ecef;border-radius:.6rem;padding:12px;background:#fff;cursor:pointer;display:flex;align-items:center;gap:12px;transition:box-shadow .15s, transform .05s}
  .course-card:hover{box-shadow:0 .5rem 1rem rgba(0,0,0,.06); transform:translateY(-1px)}
  .course-card.active{border-color:#0d6efd; box-shadow:0 0 0 .15rem rgba(13,110,253,.15)}
  .course-thumb{width:72px;height:72px;object-fit:contain;background:#f8f9fa;border-radius:.4rem;flex:0 0 72px}

  /* Module board */
  .module-board{display:grid;gap:14px}
  .mod-group{background:#fff;border:1px solid #e9ecef;border-radius:.6rem;overflow:hidden}
  .mod-head{display:flex;justify-content:space-between;align-items:center;padding:10px 12px;border-bottom:1px solid #edf2f7;background:#f8fafc}
  .mod-title{font-weight:700;color:#0b5ed7}
  .mod-meta{font-size:.85rem;color:#198754;display:flex;align-items:center;gap:6px}
  .mod-meta .count{font-weight:700}
  .mod-list{list-style:none;margin:0;padding:6px 12px}
  .mod-item{display:flex;align-items:center;gap:10px;padding:7px 2px}
  .mod-index{width:18px;text-align:center;color:#adb5bd;font-weight:600;user-select:none}
  .mod-row{display:flex;align-items:center;gap:10px;flex:1;min-width:0}
  .mod-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
  .mod-dots{flex:1;border-bottom:1px dashed #9ec5fe;opacity:.7;margin-top:6px}
  .mod-pill{font-size:.72rem;padding:2px 8px;border-radius:999px;border:1px solid #ef9a9a;background:#fff5f5;color:#c62828;white-space:nowrap}
  .mod-item:nth-child(even){background:linear-gradient(to right,rgba(13,110,253,.03),rgba(13,110,253,0))}

  /* =============================
     Compact Batch Board (minimal)
     ============================= */
  :root{ --bg:#fff; --border:#e5e7eb; --muted:#6b7280; --accent:#0d6efd; --accent-soft:#f3f8ff; --good:#0aa2a8; --full:#98a1aa; }
  .acc-body{display:none;}
  .acc-group.open .acc-body{display:block;}
  #batchBoard.compact-batches .acc-group{border:1px solid var(--border);border-radius:5px;background:#fff;overflow:hidden}
  #batchBoard.compact-batches .acc-head{display:flex;align-items:center;justify-content:space-between;padding:6px 5px;cursor:pointer;background:#fafbfc;border-bottom:1px solid var(--border)}
  #batchBoard.compact-batches .acc-left{display:flex;align-items:center;gap:5px}
  #batchBoard.compact-batches .acc-idx{width:24px;height:24px;border-radius:999px;background:#6b7280;color:#fff;display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.72rem}
  #batchBoard.compact-batches .acc-title{font-weight:600;color:#0b5ed7}
  #batchBoard.compact-batches .acc-status{font-size:1rem;color:#157347}
  #batchBoard.compact-batches .acc-body{padding:5px;background:#fff}
  #batchBoard.compact-batches .batch-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,300px));justify-content:flex-start;gap:10px}
  #batchBoard.compact-batches .batch-card{position:relative;border:1px solid var(--border);border-radius:8px;background:var(--bg);cursor:pointer;transition:box-shadow .15s ease, transform .05s ease, border-color .15s ease}
  #batchBoard.compact-batches .batch-card:hover{box-shadow:0 .4rem .9rem rgba(0,0,0,.05);transform:translateY(-1px)}
  #batchBoard.compact-batches .batch-card.selected{outline:2px solid var(--accent);background:#f8fbff}
  #batchBoard.compact-batches .batch-top{padding:6px 8px;background:var(--accent-soft);font-weight:700;text-align:center;font-size:.95rem}
  #batchBoard.compact-batches .batch-body{display:flex;align-items:stretch;min-height:52px}
  #batchBoard.compact-batches .batch-seats{width:56px;min-width:56px;text-align:center;background:#f4f9f2;border-right:1px solid var(--border);display:flex;flex-direction:column;justify-content:center;padding:6px 0}
  #batchBoard.compact-batches .batch-seats .num{font-size:20px;line-height:1;font-weight:800;color:#1f7a32}
  #batchBoard.compact-batches .batch-seats .lbl{font-size:.65rem;color:#6b7280}
  #batchBoard.compact-batches .batch-details{flex:1;padding:6px 8px}
  #batchBoard.compact-batches .batch-details .line{font-size:.85rem}
  #batchBoard.compact-batches .batch-details .muted{font-size:.72rem;color:#6b7280}
  #batchBoard.compact-batches .batch-footer{padding:6px 8px;text-align:center;font-weight:700;color:#fff;border-top:1px solid var(--border)}
  #batchBoard.compact-batches .batch-footer.ok{background:#0aa2a8}
  #batchBoard.compact-batches .batch-footer.full{background:#98a1aa}
  #batchSelect.d-hide{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
  @media (max-width:600px){#batchBoard.compact-batches .batch-grid{grid-template-columns:1fr}}
</style>
<style>
/* ============================================
   Compact overrides – New Registration only
   (content area only; header/sidebar untouched)
   ============================================ */
.ec-main, .rms-content { font-size:12.25px; }

/* Titles + buttons */
.ec-main h1, .ec-main h2, .rms-content h1, .rms-content h2 { margin-bottom:.4rem; }
.ec-main .btn, .rms-content .btn{ padding:.28rem .6rem; font-size:.84rem; border-radius:.35rem; }
.ec-main .btn-lg, .rms-content .btn-lg{ padding:.38rem .7rem; font-size:.9rem; }

/* Inputs / selects */
.ec-main .form-control, .ec-main .form-select,
.rms-content .form-control, .rms-content .form-select{
  height:2.05rem; padding:.32rem .55rem; font-size:.85rem; border-radius:.35rem;
}

/* Progress bar */
.ec-main .progressbar li, .rms-content .progressbar li{ font-size:.95rem; }
.ec-main .progressbar li:before, .rms-content .progressbar li:before{
  height:4px; margin:0 6px 6px; border-radius:999px;
}

/* White panels */
.ec-main .form-section, .rms-content .form-section{
  padding:10px; border-radius:.45rem;
}

/* Tables (Fee Plan, Students, etc.) */
.ec-main .table, .rms-content .table{ font-size:.9rem; }
.ec-main .table th, .ec-main .table td,
.rms-content .table th, .rms-content .table td{ padding:.45rem .55rem; }
.ec-main .table-tight td, .ec-main .table-tight th,
.rms-content .table-tight td, .rms-content .table-tight th{ padding:.35rem .45rem; }

/* ===== Course cards ===== */
.ec-main .course-card, .rms-content .course-card{ padding:10px; gap:10px; border-radius:.5rem; }
.ec-main .course-thumb, .rms-content .course-thumb{
  width:56px; height:56px; flex:0 0 56px; border-radius:.35rem;
}

/* ===== Modules list ===== */
.ec-main .module-board, .rms-content .module-board{ gap:10px; }
.ec-main .mod-head, .rms-content .mod-head{ padding:8px 10px; }
.ec-main .mod-title, .rms-content .mod-title{ font-size:1rem; }
.ec-main .mod-meta, .rms-content .mod-meta{ font-size:.78rem; }
.ec-main .mod-list, .rms-content .mod-list{ padding:6px 10px; }
.ec-main .mod-item, .rms-content .mod-item{ padding:6px 2px; }
.ec-main .mod-index, .rms-content .mod-index{ width:16px; font-size:.75rem; }
.ec-main .mod-pill, .rms-content .mod-pill{ font-size:.68rem; padding:1px 6px; }

/* ===== Batch board (cards) ===== */
#batchBoard.compact-batches .acc-head{ padding:4px 6px; }
#batchBoard.compact-batches .acc-idx{ width:18px; height:18px; font-size:.66rem; }
#batchBoard.compact-batches .batch-grid{
  grid-template-columns:repeat(auto-fill,minmax(260px,260px));
  gap:8px;
}
#batchBoard.compact-batches .batch-card{ border-radius:6px; }
#batchBoard.compact-batches .batch-top{ padding:5px 8px; font-size:.88rem; }
#batchBoard.compact-batches .batch-body{ min-height:46px; }
#batchBoard.compact-batches .batch-seats{ width:50px; min-width:50px; padding:5px 0; }
#batchBoard.compact-batches .batch-seats .num{ font-size:16px; }
#batchBoard.compact-batches .batch-seats .lbl{ font-size:.6rem; }
#batchBoard.compact-batches .batch-details{ padding:5px 8px; }
#batchBoard.compact-batches .batch-details .line{ font-size:.82rem; }
#batchBoard.compact-batches .batch-details .muted{ font-size:.7rem; }
#batchBoard.compact-batches .batch-footer{ padding:5px 8px; font-size:.86rem; }

/* Search dropdown under "Find Existing Student" */
.ec-main .search-results, .rms-content .search-results{ max-height:220px; }
.ec-main .search-results div, .rms-content .search-results div{ padding:6px 9px; }

/* Spacing around the page */
.ec-main .container-fluid, .rms-content .container-fluid{
  padding-top:.7rem!important; padding-bottom:.7rem!important;
}
</style>


  <style>
    .ec-success-compact .head{display:flex;align-items:center;gap:.5rem;margin-bottom:.25rem}
    .ec-success-compact .head i{font-size:1.05rem}
    .ec-success-compact .note{margin:0 0 .4rem 0;font-size:.85rem;color:#0c0e0f}
    .ec-success-compact .line{display:flex;flex-wrap:wrap;gap:1rem .75rem}
    .ec-success-compact .chip{white-space:nowrap;font-size:.95rem}
    .ec-success-compact .chip b{font-weight:700}
    .ec-success-compact .badge[class*="text-bg-"],
.ec-success-compact .chip,
.ec-success-compact .chip b{
  color:#000 !important;
}
  </style>
  <style>
/* === Step 3 – Pretty batch cards + schedule panel === */
#batchBoard.pretty .batch-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(390px,1fr));gap:12px}
.batch-card.pro{border:1px solid #cde4e4;border-radius:6px;overflow:hidden;background:#fff;transition:box-shadow .15s,transform .05s}
.batch-card.pro:hover{box-shadow:0 .6rem 1.2rem rgba(0,0,0,.06);transform:translateY(-1px)}
.batch-card.pro.selected{
  outline:2px solid #dc3545 !important;
  border-color:#dc3545 !important;
  background:#fff5f5 !important;
  box-shadow:0 0 0 3px rgba(220,53,69,.15) !important;
}

.batch-card.pro.selected .bc-top{
  background:#ffe5e9 !important;
  border-bottom:1px solid #f5b8c2 !important;
  color:#b42318 !important;
}

.batch-card.pro.selected .bc-foot{
  background:#dc3545 !important;
  color:#fff !important;
}
.bc-top{background:#e8f6f6;border-bottom:1px solid #cde4e4;text-align:center;font-weight:700;color:#0b6b6b;padding:8px 10px;font-size:.95rem}
.bc-sub{background:#f6f7f9;border-bottom:1px solid #e5e7eb;text-align:center;color:#6b7280;padding:6px 10px;font-size:.82rem}

.bc-body{display:flex;align-items:stretch;min-height:92px}
.bc-seats{width:78px;min-width:78px;display:flex;flex-direction:column;justify-content:center;align-items:center;background:#e7f2e5;border-right:1px solid #e0e6df}
.bc-seats .num{background:#4c9a2a;color:#fff;border-radius:6px;width:50px;height:50px;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:22px}
.bc-seats .lbl{font-size:.72rem;color:#335c20;margin-top:6px}

.bc-details{flex:1;padding:10px 12px}
.bc-line{display:flex;align-items:center;gap:8px;justify-content:center}
.bc-line .n{color:#a20083;font-weight:800}
.bc-line .t{color:#6b7280;font-size:.8rem}
.bc-date{text-align:center;margin-top:10px}
.bc-date .d{font-weight:700}
.bc-date .lbl{font-size:.74rem;color:#6b7280}

.bc-foot{padding:8px 10px;text-align:center;color:#fff;border-top:1px solid #e5e7eb;font-weight:700}
.bc-foot.ok{background:#007a7e}
.bc-foot.full{background:#98a1aa}

/* Schedule panel */
#batchSchedulePane .notice{background:#fff3cd;border:1px solid #ffe69c;border-radius:6px;padding:10px 12px;color:#6b5d00}
#batchSchedulePane .tl{margin-top:10px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;padding:12px}
#batchSchedulePane .tl-line{height:4px;background:#f1f3f5;margin:8px 12px;border-radius:999px}
#batchSchedulePane .tl-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}
#batchSchedulePane .mil{text-align:center}
#batchSchedulePane .mil .dot{width:22px;height:22px;border-radius:50%;margin:0 auto 6px;background:#adb5bd}
#batchSchedulePane .mil.done .dot{background:#dc3545}
#batchSchedulePane .mil.current .dot{background:#dc3545;box-shadow:0 0 0 2px #ffe5e9 inset}
#batchSchedulePane .mil .lbl{font-size:.78rem;color:#6b7280}
#batchSchedulePane .mil .date{font-weight:700}
#batchSchedulePane .fromnow{display:inline-block;background:#dc3545;color:#fff;border-radius:4px;padding:2px 8px;font-size:.75rem}
#batchSchedulePane .muted{font-size:.75rem;color:#6b7280}
.batch-tip{
  background:#e6f4f7;border:1px solid #cfe8ef;color:#0b7285;
  border-radius:4px;padding:8px 10px;font-size:.86rem
}
.batch-tip b{font-weight:700}

#batchSchedulePane .mil .ico{font-size:1.1rem;margin-bottom:4px;display:inline-block;color:#adb5bd}
#batchSchedulePane .mil.done .ico,
#batchSchedulePane .mil.current .ico{color:#dc3545}

#batchBoard .acc-group{ margin-bottom:10px; }
#batchBoard .acc-head{
  padding:8px 10px; display:flex; align-items:center; justify-content:space-between;
  background:#fafbfc; border:1px solid #e5e7eb; border-bottom-color:#e5e7eb; cursor:pointer;
}
#batchBoard .acc-left{ display:flex; align-items:center; gap:8px; }
#batchBoard .acc-idx{
  width:22px; height:22px; min-width:22px; border-radius:999px;
  background:#0b5ed7; color:#fff; display:flex; align-items:center; justify-content:center;
  font-weight:700; font-size:.72rem;
}
#batchBoard .acc-title{ font-weight:600; color:#0b5ed7; line-height:1.2; }


</style>
<style>
  /* --- batch code tag + locked look --- */
  .bc-code{ text-align:center; margin:4px 0 6px }
  .bc-code .tag{
    display:inline-block; padding:2px 8px; border-radius:999px;
    background:#e9ecef; color:#0b5ed7; font-weight:700; font-size:.8rem
  }

  .batch-card.locked{
    opacity:.75; cursor:not-allowed; position:relative; pointer-events:none;
  }
  .batch-card.locked::after{
    content: 'LOCKED';
    position:absolute; top:6px; right:6px;
    font-size:.7rem; background:#6c757d; color:#fff; padding:2px 6px; border-radius:4px;
  }
  .batch-card.locked .bc-foot{ background:#6c757d !important; }
</style>

</head>
<body>
<?php
$ACTIVE = 'registrations'; // <-- highlight current menu item
require_once __DIR__ . '/../includes/header.php';
require_once __DIR__ . '/../includes/sidebar.php';
?>
<main class="ec-main">


<!-- now your page content inside <main class="ec-main"> -->
<div class="container-fluid py-4">
  <div class="bg-white shadow-sm rounded p-3 p-md-4">

    <div class="d-flex align-items-center justify-content-between mb-3">
      <h4 class="mb-0">New Registration</h4>
      <div class="mini-hint">Complete all 6 steps and click <b>Confirm &amp; Register</b>.</div>
    </div>

<?php if (isset($_GET['success']) && $_GET['success'] == '1'): ?>
  <?php
    // session should already be active via ec_require_login(); this is harmless if active:
    if (session_status() !== PHP_SESSION_ACTIVE) { @session_start(); }

    $flash    = (isset($_SESSION['reg_flash']) && is_array($_SESSION['reg_flash'])) ? $_SESSION['reg_flash'] : [];
    $numbers  = isset($flash['numbers']) && is_array($flash['numbers']) ? $flash['numbers'] : [];

    $ref = htmlspecialchars((string)($flash['reference_no']  ?? '—'), ENT_QUOTES, 'UTF-8');
    $nec = htmlspecialchars((string)($flash['center_reg_no'] ?? '—'), ENT_QUOTES, 'UTF-8');
    $aem = htmlspecialchars((string)($flash['academic_email']?? '—'), ENT_QUOTES, 'UTF-8');
    $apw = htmlspecialchars((string)(
              ($flash['academic_password'] ?? '') !== '' ? $flash['academic_password'] : 'Set by admin / emailed'
            ), ENT_QUOTES, 'UTF-8');

    // New vs existing student — controls whether we show the single EC chip
    $is_existing    = !empty($flash['is_existing']);
    $show_single_ec = (!$is_existing && $ref !== '—');
  ?>
  <div class="alert alert-success border-success ec-success-compact">
    <div class="head">
      <i class="bi bi-check-circle-fill text-success"></i>
      <strong>Registration completed!</strong>
    </div>
    <p class="note">Share these with the student or print this page.</p>

    <div class="line">
      <span class="chip badge text-bg-success-subtle border border-success-subtle">
        NEC: <b><?= $nec ?></b>
      </span>

      <?php if ($show_single_ec): ?>
        <span class="chip badge text-bg-primary-subtle border border-primary-subtle">
          EC: <b><?= $ref ?></b>
        </span>
      <?php endif; ?>

      <?php if ($aem !== '—'): ?>
        <span class="chip badge text-bg-info-subtle border border-info-subtle">
          Academic Email: <b><?= $aem ?></b>
        </span>
        <span class="chip badge text-bg-secondary-subtle border border-secondary-subtle">
          Password: <b><?= $apw ?></b>
        </span>
      <?php endif; ?>
    </div>

    <?php if ($numbers): ?>
      <hr class="my-2">
      <div class="small">
        <strong>Per-course EC numbers:</strong>
        <ul class="m-0 mt-1">
          <?php foreach ($numbers as $row): ?>
            <li>
              <?= htmlspecialchars($row['course_name'] ?? ('Course #'.(int)($row['course_id'] ?? 0)), ENT_QUOTES, 'UTF-8') ?>
              — EC: <b><?= htmlspecialchars($row['reference_no'] ?? '-', ENT_QUOTES, 'UTF-8') ?></b>
            </li>
          <?php endforeach; ?>
        </ul>
      </div>
    <?php endif; ?>
  </div>
  <?php if (isset($_SESSION['reg_flash'])) { unset($_SESSION['reg_flash']); } // show once ?>
<?php endif; ?>




    <ul class="progressbar mb-3">
      <li class="active">Course</li>
      <li>Modules</li>
      <li>Batch</li>
      <li>Fee Plan</li>
      <li>Student</li>
      <li>Confirm</li>
    </ul>

<form id="registrationForm" method="POST" action="submit_registration.php?debug=1" enctype="multipart/form-data" novalidate>
      <!-- hidden state -->
      <!-- Add this line near your other hidden inputs -->
    <input type="hidden" name="selected_course_id" id="selected_course_id">
      <input type="hidden" name="course" id="course_id">
      <input type="hidden" name="batch" id="batch_id">
      <input type="hidden" name="fee_plan_id" id="fee_plan_id">
      <input type="hidden" name="discount_method" id="discount_method">
      <input type="hidden" name="manual_discount_lkr" id="manual_discount_lkr" value="0">
      <input type="hidden" name="existing_student_id" id="existing_student_id" value="0">
<input type="hidden" name="reg_branch_id"   id="reg_branch_id"   value="<?= (int)$reg_branch_id ?>">
<input type="hidden" name="reg_branch_name" id="reg_branch_name" value="<?= htmlspecialchars((string)$reg_branch_name, ENT_QUOTES,'UTF-8') ?>">
<input type="hidden" name="preferred_due_day" id="preferred_due_day" value="">

<!-- Hidden, inside your registration form near #fee_plan_id -->
<input type="hidden" id="selected_plan_json" name="selected_plan_json">

      <!-- Step 1: Course -->
      <div class="step active" id="step-course">
        <div class="course-search mb-3">
          <input type="text" id="courseSearch" class="form-control" placeholder="Search by course name or code...">
        </div>

        <div class="row g-3" id="courseGrid">
          <?php
          $q = $conn->query("
            SELECT id, course_name AS title, COALESCE(code,'') AS code
            FROM courses
            WHERE status IS NULL OR status='Active'
            ORDER BY course_name ASC
          ");
          if (!$q) {
            echo '<div class="col-12"><div class="alert alert-danger">Database query error: ' . htmlspecialchars($conn->error) . '</div></div>';
          } else {
            $rowCount = 0;
            while ($c = $q->fetch_assoc()):
              $rowCount++;
              $cid   = (int)$c['id'];
              $title = trim($c['title'] ?? '');
              $code  = trim($c['code'] ?? '');
              $imgUrl = course_img_url($cid, $code);
          ?>
          <div class="col-xl-4 col-lg-6">
    <div class="course-card" 
         data-id="<?= $cid ?>" 
         data-title="<?= htmlspecialchars($title, ENT_QUOTES) ?>" 
         data-code="<?= htmlspecialchars($code, ENT_QUOTES) ?>"
         role="button"
         tabindex="0">
        <img class="course-thumb" src="<?= $imgUrl ?>" alt="<?= htmlspecialchars($code ?: $title) ?>">
        <div class="flex-grow-1">
            <div class="course-title">
                <?= htmlspecialchars($title) ?>
                <?php if($code!==''): ?>
                    <small class="text-muted"> (<?= htmlspecialchars($code) ?>)</small>
                <?php endif; ?>
            </div>
        </div>
        <div class="align-self-center">
            <span class="badge text-bg-light">Select</span>
        </div>
    </div>
</div>

            <?php endwhile;
            
            // ✅ FIX: Show error if no courses found
            if ($rowCount === 0) {
              echo '<div class="col-12"><div class="alert alert-warning">No active courses found. Please contact an administrator.</div></div>';
            }
          }
          ?>
        </div>

        <div class="mt-3 d-flex justify-content-between">
          <span class="text-muted small">Tip: click a card to select a course.</span>
          <button type="button" class="btn btn-primary next-step" id="goModules" disabled>Next</button>
        </div>
      </div>

      <!-- Step 2: Modules -->
      <div class="step" id="step2">
        <div class="form-section">
          <div class="d-flex justify-content-between align-items-center mb-2">
            <div>
              <div class="fw-semibold">Modules for: <span id="chosenCourseName" class="text-primary"></span></div>
              <div class="mini-hint">If the course is a bundle/dual, modules of all parts are listed.</div>
            </div>
          </div>
          <div class="table-responsive">
            <table class="table table-tight table-striped align-middle mb-0" id="modulesTable">
              <thead class="table-light">
                <tr><th style="width:60px">#</th><th>Module</th></tr>
              </thead>
              <tbody>
                <tr><td colspan="2" class="text-center text-muted">Pick a course in Step 1.</td></tr>
              </tbody>
            </table>
          </div>
        </div>
        <div class="d-flex justify-content-between mt-3">
          <button type="button" class="btn btn-secondary prev-step">Back</button>
          <button type="button" class="btn btn-primary next-step">Next</button>
        </div>
      </div>

<!-- Step 3: Batch -->
<div class="step" id="step3">
  <div class="form-section">
    <div class="row g-3">
        <div class="batch-tip mb-2">
  Click on any available batch to view the class schedule. <b>MAKE SURE</b> there are <b>NO</b> conflicts before you proceed.
</div>

      <!-- Left: cards -->
      <div class="col-xl-7">
        <label class="form-label">Convenient Batch(es)</label>
        <select class="form-select d-hide" id="batchSelect"><option value="">Select Batch</option></select>
        <div class="mini-hint mt-2">Click a batch card to select it.</div>
        <div id="batchBoard" class="mt-2 pretty">
          <div class="p-3 text-muted text-center">Pick a course first.</div>
        </div>
      </div>

      <!-- Right: schedule pane -->
      <div class="col-xl-5">
        <div id="batchSchedulePane">
          <div class="p-3 text-muted text-center">Select a batch to see its schedule.</div>
        </div>
      </div>
    </div>
  </div>
  <div class="d-flex justify-content-between mt-3">
    <button type="button" class="btn btn-secondary prev-step">Back</button>
    <button type="button" class="btn btn-primary next-step">Next</button>
  </div>
</div>


      <!-- Step 4: Fee Plan – One-time vs Installment (+ presets, manual/method discounts) -->
      <div class="step" id="step4">
        <div class="row g-3">
          <!-- LEFT: Plan selector -->
          <div class="col-lg-6">
            <div class="card">
              <div class="card-header bg-light"><strong>Choose How to Pay</strong></div>
              <div class="card-body">
                <ul class="nav nav-pills mb-3" id="feeModeTabs" role="tablist">
                  <li class="nav-item" role="presentation">
                    <button class="nav-link active" id="onetab" data-bs-toggle="pill" data-bs-target="#onePane"
                            type="button" role="tab" aria-controls="onePane" aria-selected="true">
                      One-time Payment
                    </button>
                  </li>
                  <li class="nav-item" role="presentation">
                    <button class="nav-link" id="instab" data-bs-toggle="pill" data-bs-target="#instPane"
                            type="button" role="tab" aria-controls="instPane" aria-selected="false">
                      Installment Plan
                    </button>
                  </li>
                </ul>

                <div class="tab-content">
                  <!-- One-time -->
                  <div class="tab-pane fade show active" id="onePane" role="tabpanel" aria-labelledby="onetab">
                    <div id="oneTimeOptions" class="list-group">
                      <div class="p-3 text-muted text-center">Select a course to view options.</div>
                    </div>
                  </div>
                  <!-- Installments -->
                  <div class="tab-pane fade" id="instPane" role="tabpanel" aria-labelledby="instab">
                    <div id="installmentOptions" class="list-group">
                      <div class="p-3 text-muted text-center">Select a course to view options.</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>

            <!-- Method + Manual discount (unchanged) -->
            <div class="card mt-3" id="payment-method-card" style="display:none">
              <div class="card-body">
                <h6 class="text-center mb-1"><strong>Extra Discount – Based on Payment Method</strong></h6>
                <p class="small text-muted text-center mb-2">Choosing one locks the payment method at the cashier.</p>
                <div class="form-check ms-2">
                  <input class="form-check-input dm-radio" type="radio" name="dm" id="dm_cash" value="cash">
                  <label class="form-check-label" for="dm_cash">10% for Cash payments</label>
                </div>
                <div class="form-check ms-2">
                  <input class="form-check-input dm-radio" type="radio" name="dm" id="dm_visa" value="card_visa">
                  <label class="form-check-label" for="dm_visa">7.5% for Card (Master/Visa)</label>
                </div>
                <div class="form-check ms-2 mb-2">
                  <input class="form-check-input dm-radio" type="radio" name="dm" id="dm_amex" value="amex">
                  <label class="form-check-label" for="dm_amex">7% for Card (Amex)</label>
                </div>
                <button type="button" class="btn btn-outline-success btn-sm" id="btnManualDiscount">+ Manual Discount</button>
                <div class="mini-hint mt-2">Manual discount is course-scoped and will be subtracted from LKR total.</div>
              </div>
            </div>
          </div>

          <!-- RIGHT: Totals + Installments -->
<div class="col-lg-6">

  <div class="card">
    <div class="card-header bg-light"><strong>Student's Payment Plan</strong></div>
    <div class="card-body p-0">
      <table class="table table-bordered table-tight m-0">
  <tbody>
    <tr>
      <th style="width:55%">Course Fee (LKR)</th>
      <td class="text-end" id="courseFeeLKR">0.00</td>
    </tr>
    <tr>
      <th>Registration Fee (LKR)</th>
      <td class="text-end" id="regFeeLKR">0.00</td>
    </tr>
    <tr>
      <th>Certificate Fee (USD)</th>
      <td class="text-end" id="certFeeUSD">0.00</td>
    </tr>

    <tr class="table-light">
      <th>Sub Total (LKR)</th>
      <td class="text-end" id="subTotalLKR">0.00</td>
    </tr>
    <tr class="table-light">
      <th>Sub Total (USD)</th>
      <td class="text-end" id="subTotalUSD">0.00</td>
    </tr>

    <tr class="table-warning">
      <th>Plan Discount (LKR)</th>
      <td class="text-end text-danger" id="planDiscLKR">0.00</td>
    </tr>
    <tr class="table-warning">
      <th>Manual Discount (LKR)</th>
      <td class="text-end text-danger" id="discLKR">0.00</td>
    </tr>
    <tr class="table-warning">
      <th>Method Discount (LKR)</th>
      <td class="text-end text-danger" id="methodDiscLKR">0.00</td>
    </tr>

    <tr class="table-success">
      <th class="fw-bold">Total Payable (LKR)</th>
      <td class="text-end fw-bold" id="totalLKR">0.00</td>
    </tr>
    <tr class="table-info">
      <th class="fw-bold">Total Payable (USD)</th>
      <td class="text-end fw-bold" id="totalUSD">0.00</td>
    </tr>
  </tbody>
</table>

    </div>
  </div>

  <div class="card mt-3">
    <div class="card-header bg-light"><strong>Installment Breakdown</strong></div>
    <div class="card-body p-0">
      <div id="instWrap" class="list-group list-group-flush">
        <div class="p-3 text-muted text-center">Select a plan to see installments.</div>
      </div>
    </div>
  </div>

  <!-- ✅ Preferred Due Day (must be INSIDE this col) -->
  <div class="card mt-2" id="prefDueWrap" style="display:none;">
    <div class="card-body d-flex align-items-center justify-content-end gap-2">
      <label class="mb-0 fw-semibold">Preferred Installment Due Day :</label>

      <select class="form-select" id="prefDueDaySelect" style="width:90px">
        <?php for($d=1;$d<=31;$d++): ?>
          <option value="<?= $d ?>"><?= $d ?></option>
        <?php endfor; ?>
      </select>

      <button type="button" class="btn btn-primary" id="btnApplyPrefDueDay">APPLY DATE</button>
    </div>
  </div>

  <div class="d-flex justify-content-end mt-3">
    <button type="button" class="btn btn-primary next-step">Continue</button>
  </div>
  </div>

        <div class="d-flex justify-content-start mt-3">
          <button type="button" class="btn btn-secondary prev-step">Previous</button>
        </div>
      </div>
      </div>


      <!-- Step 5: Student (Add Student button; form hidden until clicked) -->
      <div class="step" id="step5">
        <div class="row g-3">
          <!-- LEFT: search existing -->
          <div class="col-lg-4">
            <div class="form-section position-relative">
              <label class="form-label">Find Existing Student</label>
              <input type="text" id="studentSearch" class="form-control" placeholder="Search by NIC, Name or Reg No">
              <div id="studentResults" class="search-results d-none"></div>
              <div class="mini-hint mt-2">Selecting a result will auto-fill the form on the right.</div>

              <div class="d-grid gap-2 mt-2">
                <button type="button" class="btn btn-outline-secondary" id="btnClearStudent">Clear selection</button>
                <button type="button"
                        class="btn btn-primary"
                        id="btnAddStudent"
                        data-bs-toggle="collapse"
                        data-bs-target="#step-student"
                        aria-expanded="false"
                        aria-controls="step-student">
                  + Add Student
                </button>
              </div>
            </div>
          </div>

          <!-- RIGHT: student details (collapsed by default; same format) -->
          <div class="col-lg-8">
            <div id="step-student" class="collapse">
              <div class="form-section">
                <h5>Personal Information</h5>
                <div class="row g-3">
                  <!-- Title -->
<div class="col-md-3">
  <select id="st_title" name="title" class="form-select">
    <option value="">Title</option>
    <option>Mr</option>
    <option>Ms</option>
    <option>Mrs</option>
    <option>Miss</option>
    <option>Mx</option>
    <option>Dr</option>
    <option>Prof</option>
    <option>Rev</option>
    <option>Other</option>
  </select>
</div>

                  <div class="col-md-9"><input type="text" id="st_full_name" name="full_name" class="form-control" placeholder="Full Name" required></div>
                  <div class="col-md-6">
                    <select id="st_gender" name="gender" class="form-control" required><option value="">Gender</option><option>Male</option><option>Female</option></select>
                  </div>
                  <div class="col-md-6"><input type="date" name="dob" class="form-control"></div>
                  <!-- Nationality -->
<div class="col-md-6">
  <select id="st_nationality" name="nationality" class="form-select">
    <option value="">Nationality</option>
    <option>Sinhala</option>
    <option>Tamil</option>
    <option>Muslim</option>
  </select>
</div>

                  <div class="col-md-6"><input type="text" id="st_nic" name="nic" class="form-control" placeholder="NIC Number"></div>
                  <div class="col-md-6"><input type="file" id="photo" name="photo" class="form-control" accept="image/*"></div>
                </div>
              </div>

              <div class="form-section">
                <h5>Contact Information</h5>
                <div class="row g-3">
                  <div class="col-md-6"><input type="text" id="st_mobile" name="mobile" class="form-control" placeholder="Mobile Number" required></div>
                  <div class="col-md-6"><input type="email" name="email" class="form-control" placeholder="Email Address"></div>
                  <div class="col-md-6"><input type="text" name="address1" class="form-control" placeholder="Address Line 1"></div>
                  <div class="col-md-6"><input type="text" name="address2" class="form-control" placeholder="Address Line 2"></div>
                  <div class="col-md-6"><input type="text" name="city" class="form-control" placeholder="City"></div>
                  <div class="col-md-6"><input type="text" name="country" class="form-control" placeholder="Country"></div>
                </div>
              </div>

              <div class="form-section">
                <h5>Guardian Information</h5>
                <div class="row g-3">
                  <div class="col-md-6"><input type="text" name="guardian_name" class="form-control" placeholder="Guardian Name"></div>
                  <div class="col-md-6"><input type="text" name="guardian_relationship" class="form-control" placeholder="Relationship"></div>
                  <div class="col-md-6"><input type="text" name="guardian_contact" class="form-control" placeholder="Guardian Contact Number"></div>
                </div>
              </div>
            </div>

            <div class="mt-3 d-flex justify-content-between">
              <button type="button" class="btn btn-secondary prev-step">Previous</button>
              <button type="button" class="btn btn-primary next-step">Next</button>
            </div>
          </div>
        </div>
      </div>

      <!-- Step 6: Confirm -->
      <div class="step" id="step6">
        <div class="form-section">
          <h6 class="mb-3">Confirm Registration</h6>
          <ul class="list-group mb-3">
            <li class="list-group-item">Course: <span id="cConfirm"></span></li>
            <li class="list-group-item">Modules: <span id="mConfirm"></span></li>
            <li class="list-group-item">Batch: <span id="bConfirm"></span></li>
            <li class="list-group-item">Fee Plan: <span id="pConfirm"></span></li>
            <li class="list-group-item">Totals: <span id="tConfirm"></span></li>
            <li class="list-group-item">Student: <span id="sConfirm"></span></li>
          </ul>
          <div class="d-flex justify-content-between">
            <button type="button" class="btn btn-secondary prev-step">Previous</button>
            <button type="submit" id="btnConfirmRegister" class="btn btn-success">Confirm &amp; Register</button>
          </div>
        </div>
      </div>
    </form>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Debug: Check if jQuery and elements are loaded
$(document).ready(function() {
    console.log("Document ready - checking elements:");
    console.log("Course cards found:", $("#courseGrid .course-card").length);
    console.log("Course ID field:", $("#course_id").length);
    console.log("Selected course ID field:", $("#selected_course_id").length);
    
    // Test if course cards have data
    $("#courseGrid .course-card").each(function(index) {
        console.log("Card " + index + " data:", $(this).data());
    });
});

/**
 * Client-side photo shrinker for <input name="photo">.
 * - Max dimension 900px, JPEG ~0.82 quality
 * - Tries to keep file <= ~600 KB (adjustable)
 */
(function () {
  const form   = document.getElementById('registrationForm');
  const input  = document.getElementById('photo');    // input[name=photo]
  const button = document.getElementById('btnConfirmRegister');

  if (!form || !input) return;

  const MAX_DIM           = 900;              // pixels (longest edge)
  const DEFAULT_QUALITY   = 0.82;             // initial JPEG quality (matches server)
  const TARGET_MAX_BYTES  = 600 * 1024;       // ~600 KB target (tweak if you like)
  const MIME_OUT          = 'image/jpeg';

  // Utility: read a File -> HTMLImageElement
  function loadImage(file) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onerror = () => reject(new Error('FileReader failed'));
      reader.onload = () => {
        const img = new Image();
        img.onload = () => resolve(img);
        img.onerror = () => reject(new Error('Image decode failed'));
        img.src = reader.result;
      };
      reader.readAsDataURL(file);
    });
  }

  // Resize + encode -> Blob (JPEG)
  async function shrinkToJpeg(file) {
    // If it's already small, skip work.
    if (file.size <= TARGET_MAX_BYTES && /^image\/(jpeg|jpg)$/i.test(file.type)) {
      return file;
    }

    const img = await loadImage(file);

    const w = img.naturalWidth || img.width;
    const h = img.naturalHeight || img.height;
    const scale = Math.min(1, MAX_DIM / Math.max(w, h));
    const outW = Math.max(1, Math.round(w * scale));
    const outH = Math.max(1, Math.round(h * scale));

    const canvas = document.createElement('canvas');
    canvas.width = outW; canvas.height = outH;
    const ctx = canvas.getContext('2d', { alpha: false });
    ctx.imageSmoothingQuality = 'high';
    ctx.drawImage(img, 0, 0, outW, outH);

    // Try a couple of qualities to stay under TARGET_MAX_BYTES
    let quality = DEFAULT_QUALITY;
    let blob = await new Promise(res => canvas.toBlob(res, MIME_OUT, quality));

    if (blob && blob.size > TARGET_MAX_BYTES) {
      // second attempt ~0.7
      quality = 0.7;
      blob = await new Promise(res => canvas.toBlob(res, MIME_OUT, quality));
    }
    if (blob && blob.size > TARGET_MAX_BYTES) {
      // final attempt ~0.6
      quality = 0.6;
      blob = await new Promise(res => canvas.toBlob(res, MIME_OUT, quality));
    }

    // Make a File so it behaves like the original
    const niceName = (file.name || 'photo').replace(/\.[^.]+$/,'') + '.jpg';
    return new File([blob], niceName, { type: MIME_OUT, lastModified: Date.now() });
  }

  // Replace the chosen file with the shrunken one
  async function compressInputFile() {
    const file = input.files && input.files[0];
    if (!file || !/^image\//i.test(file.type)) return;

    try {
      // UI feedback
      if (button) { button.disabled = true; button.textContent = 'Optimizing photo…'; }

      const small = await shrinkToJpeg(file);

      // Replace the file in the input using DataTransfer
      const dt = new DataTransfer();
      dt.items.add(small);
      input.files = dt.files;

      // Optional: show quick size info in console
      console.log(`Photo compressed: ${Math.round(file.size/1024)}KB -> ${Math.round(small.size/1024)}KB`);
    } catch (err) {
      console.warn('Photo compression skipped:', err);
      // If anything fails, we just keep the original file.
    } finally {
      if (button) { button.disabled = false; button.textContent = 'Confirm & Register'; }
    }
  }

  // Compress as soon as a file is picked…
  input.addEventListener('change', compressInputFile);

  // …and as a safety net, compress right before submit
  form.addEventListener('submit', async (e) => {
    // If there's a photo and it looks large, try to compress before sending.
    const f = input.files && input.files[0];
    if (f && f.size > TARGET_MAX_BYTES) {
      e.preventDefault();
      await compressInputFile();
      form.submit(); // re-submit with the smaller file
    }
  });
})();
</script>

<script>
(function(){
  let currentStep = 0;
  const steps = $(".step");
  const pb = $(".progressbar li");
  const modulesCache = [];
  let selectedCourseName = "";

  // ---------- Fee plan state (shared) ----------
  //let selectedPlan = null;            // {type:'one'|'inst', plan_id, installments, totals:{cL,rL,cU}, preset_lkr, name}
  //let methodDiscPct = 0;              // cash/visa/amex
  //let coursePresets = [];             // e.g. [{code:'25K',label:'25K OFF',amount_lkr:25000}]
  //let currentInstallmentPlan = null;  // standard plan used for sums/installment schedule

  // ---------- Batches ----------
  let selectedBatchIds = new Set();
  let multiBatchMode = false;
  let requiredBatchCount = 1;   // bundle/dual courses walata required count

  function showStep(i){
    steps.removeClass("active").hide();
    steps.eq(i).addClass("active").fadeIn(90);
    pb.removeClass("active");
    for(let x=0;x<=i;x++) pb.eq(x).addClass("active");

    const isStep5 = steps.eq(i).attr("id") === "step5";
    if (!isStep5) {
      const el = document.getElementById('step-student');
      if (el) bootstrap.Collapse.getOrCreateInstance(el, {toggle:false}).hide();
    }
  }
  function need(val,msg){ if(!val){ alert(msg); return true; } return false; }
  function currency(n){ return (parseFloat(n||0)).toFixed(2); }
  function escapeHtml(s){ return $('<div>').text(s==null?'':s).html(); }

  $("#registrationForm").on("keydown", function(e){
    if (e.key === "Enter" && currentStep !== steps.length-1) { e.preventDefault(); }
  });
  $("#courseSearch, #studentSearch").on("keydown", function(e){
    if (e.key === "Enter") { e.preventDefault(); }
  });

  // *** HARD BLOCK submit if not on last step AND if required student fields missing ***
  $("#registrationForm").on("submit", function(e){
    if (currentStep !== steps.length-1) e.preventDefault();
    if (!validateStudent(true)) {
      e.preventDefault();
      currentStep = 4; // go back to Step 5
      showStep(currentStep);
      const el = document.getElementById('step-student');
      if (el) bootstrap.Collapse.getOrCreateInstance(el, {toggle:false}).show();
      return false;
    }
  });

  // Step nav
$(".next-step").on("click", function(){
  if (currentStep===0) {
    if (need($("#course_id").val(), "Please select a course.")) return;
  }

if (currentStep===2) {
  if (LOCK_BATCH_SELECTION) {
    alert("Batch selection is currently locked.");
    return;
  }

  if (selectedBatchIds.size === 0) {
    alert("Please select at least one batch.");
    return;
  }

  // bundle course ekak nam minimum batch 2k
  if (multiBatchMode && selectedBatchIds.size < 2) {
    alert("This is a bundle course. Please select at least 2 batches before continuing.");
    return;
  }

  $("#batch_id").val([...selectedBatchIds].join(","));
}

  if (currentStep===3) {
    if (need($("#fee_plan_id").val(), "Please select a fee plan or option.")) return;
  }

  if (currentStep===4) {
    if (!validateStudent(true)) {
      const el = document.getElementById('step-student');
      if (el) bootstrap.Collapse.getOrCreateInstance(el, {toggle:false}).show();
      return;
    }
  }

  currentStep = Math.min(currentStep + 1, steps.length - 1);

  if (currentStep === steps.length - 1) {
    buildConfirm();
    updateConfirmButtonState();
  }

  showStep(currentStep);
});

$(".prev-step").on("click", function(){
  currentStep = Math.max(currentStep - 1, 0);
  showStep(currentStep);
});

 // Step 1: Courses - REPLACE THE ENTIRE SECTION
$("#courseSearch").on("input", function(){
    const q = $(this).val().toLowerCase();
    $("#courseGrid .col-xl-4, #courseGrid .col-lg-6").each(function(){
        const card = $(this).find('.course-card');
        if (card.length) {
            const hay = [card.data("title")+"", card.data("code")+""].join(" ").toLowerCase();
            $(this).toggle(hay.indexOf(q) !== -1);
        }
    });
});

// Course selection handlers
$(document).on("click", "#courseGrid .course-card", function(e){
    e.preventDefault();
    console.log("Course card clicked");
    selectCourse($(this));
});

$(document).on("keydown", "#courseGrid .course-card", function(e){
    if (e.key === "Enter" || e.key === " ") {
        e.preventDefault();
        console.log("Course card activated via keyboard");
        selectCourse($(this));
    }
});

function selectCourse($card) {
    // Remove active class from all cards
    $("#courseGrid .course-card").removeClass("active");
    
    // Reset ALL badges back to default state (this is the key fix)
    $("#courseGrid .course-card .badge")
        .removeClass('text-bg-success')
        .addClass('text-bg-light')
        .text('Select');
    
    // Add active class to selected card
    $card.addClass("active");
    
    // Get course data
    const id = $card.data("id");
    const title = $card.data("title") || "";
    const code = $card.data("code") || "";
    
    // Store in hidden fields
    $("#course_id").val(id);
    $("#selected_course_id").val(id);
    selectedCourseName = title;
    
    // Enable the next button
    $("#goModules").prop("disabled", false);
    
    // Visual feedback - ONLY for the selected card
    $card.find('.badge')
        .removeClass('text-bg-light')
        .addClass('text-bg-success')
        .text('Selected');
    
    console.log("Selected course:", id, title);
    
    // Load related data
    loadModules(id, title);
    loadBatches(id);
    loadPlans(id);
    
    // Trigger event for other components
    window.dispatchEvent(new CustomEvent('course:selected', {
        detail: { course_id: id, course_title: title, course_code: code }
    }));
}


  // Step 2: Modules  — CORRECTED
function loadModules(courseId, title){
  $("#chosenCourseName").text(title || "");
  $("#modulesTable thead").hide();
  $("#modulesTable tbody").html('<tr><td colspan="2" class="text-center text-muted">Loading…</td></tr>');

  // modules come from the modules endpoint, not batches:
  $.getJSON("../ajax/fetch_modules_from_courses.php", { course_id: courseId }, function(res){
    modulesCache.length = 0;
    if (Array.isArray(res.modules)) modulesCache.push(...res.modules);

    if (Array.isArray(res.groups) && res.groups.length){
      const groups = res.groups;
      let board = '<div class="module-board">';
      groups.forEach((g) => {
        const name = (g.course_name || "Course").toString();
        const mods = Array.isArray(g.modules) ? g.modules : [];
        if (!mods.length) return;
        board += `
          <div class="mod-group">
            <div class="mod-head">
              <div class="mod-title">${escapeHtml(name)}</div>
              <div class="mod-meta"><i class="bi bi-star-fill"></i><span class="count">${mods.length}</span><span>modules</span></div>
            </div>
            <ul class="mod-list">
              ${
                mods.length
                ? mods.map((m,i)=>(
                    `<li class="mod-item">
                       <div class="mod-index">${i+1}</div>
                       <div class="mod-row">
                         <div class="mod-text">${escapeHtml(m)}</div>
                         <div class="mod-dots"></div>
                         <div class="mod-pill">Compulsory</div>
                       </div>
                     </li>`
                  )).join("")
                : `<li class="mod-item"><div class="mod-index">–</div><div class="mod-row"><div class="mod-text text-muted">No modules listed.</div></div></li>`
              }
            </ul>
          </div>`;
      });
      board += "</div>";
      $("#modulesTable tbody").html(`<tr><td colspan="2">${board}</td></tr>`);
      return;
    }

    // basic fallback table
    $("#modulesTable thead").show();
    let rows = "";
    if (res && res.modules && res.modules.length){
      res.modules.forEach((m,i)=>{ rows += `<tr><td>${i+1}</td><td>${escapeHtml(m)}</td></tr>`; });
    } else {
      rows = '<tr><td colspan="2" class="text-center text-muted">No modules found.</td></tr>';
    }
    $("#modulesTable tbody").html(rows);
  }).fail(function(xhr, status, err){
    $("#modulesTable tbody").html(`<tr><td colspan="2" class="text-danger text-center">Failed to load modules (${status})</td></tr>`);
  });
}



// ---------- STEP 3: Batches (clickable cards + code pill) ----------

// Toggle this to hard-lock every batch (keeps the style, no clicks allowed)
const LOCK_BATCH_SELECTION = false;  // <— make sure this is FALSE so you can click

function selectBatchCard($card, toggleForMulti = false){
  if (!$card || !$card.length) return;

  const bid = $card.data('branch-id');
  const bnm = ($card.data('branch-name') || '').toString().trim();
  const id  = String($card.data('id'));
  const groupCourseId = String($card.data('course-id'));
  const isAlreadySelected = $card.hasClass('selected');

  // ---------- MULTI / BUNDLE ----------
  if (multiBatchMode) {
    if (isAlreadySelected) {
      $card.removeClass('selected');
      selectedBatchIds.delete(id);

      $(`.acc-group[data-course="${groupCourseId}"] .acc-status`).html('');
    } else {
      $card.addClass('selected');
      selectedBatchIds.add(id);

      $(`.acc-group[data-course="${groupCourseId}"] .acc-status`).html(
        '<i class="bi bi-check-circle-fill text-success"></i>'
      );

      if (bid) $('#reg_branch_id').val(String(bid));
      if (bnm) $('#reg_branch_name').val(bnm);

      renderBatchSchedule({
        open:  $card.data('open')  || '',
        start: $card.data('start') || '',
        close: $card.data('close') || '',
        end:   $card.data('end')   || ''
      });
    }
  } 
  // ---------- SINGLE COURSE ----------
  else {
    if (isAlreadySelected) {
      $card.removeClass('selected');
      selectedBatchIds = new Set();
      $('#batchSchedulePane').html('<div class="p-3 text-muted text-center">Select a batch to see its schedule.</div>');
    } else {
      $('.batch-card.pro').removeClass('selected');
      selectedBatchIds = new Set();

      $card.addClass('selected');
      selectedBatchIds.add(id);

      if (bid) $('#reg_branch_id').val(String(bid));
      if (bnm) $('#reg_branch_name').val(bnm);

      renderBatchSchedule({
        open:  $card.data('open')  || '',
        start: $card.data('start') || '',
        close: $card.data('close') || '',
        end:   $card.data('end')   || ''
      });
    }
  }

  const arr = [...selectedBatchIds];
  $('#batch_id').val(arr.join(','));
  $('#batchSelect').val(arr[0] || '');

const hasSel = $(`.acc-group[data-course="${groupCourseId}"] .batch-card.selected`).length > 0;
$(`.acc-group[data-course="${groupCourseId}"] .acc-status`).html(
  hasSel ? '<i class="bi bi-check-circle-fill text-success"></i>' : ''
);

if (!hasSel && !multiBatchMode) {
  $('#batchSchedulePane').html('<div class="p-3 text-muted text-center">Select a batch to see its schedule.</div>');
}
}
function loadBatches(courseId){
  selectedBatchIds = new Set();
  multiBatchMode   = false;
  requiredBatchCount = 1;

  $('#batch_id').val('');
  $('#batchSelect').empty().append('<option value="">Select Batch</option>');
  $('#batchBoard').html('<div class="p-3 text-muted text-center">Loading...</div>');
  $('#batchSchedulePane').html('<div class="p-3 text-muted text-center">Select a batch to see its schedule.</div>');

  $.getJSON("../ajax/fetch_modules_from_courses.php", { course_id: courseId }, function(modres){
    let groups = [];

    if (modres && Array.isArray(modres.groups) && modres.groups.length){
      groups = modres.groups.map(g => ({
        id: g.course_id,
        name: g.course_name || "Course"
      }));
    } else {
      groups = [{
        id: courseId,
        name: $("#chosenCourseName").text() || "Course"
      }];
    }

    multiBatchMode = groups.length > 1;
    requiredBatchCount = Math.max(1, groups.length);

    let html = '';
    groups.forEach((g, idx) => {
      html += `
        <div class="acc-group ${idx === 0 ? 'open' : ''}" data-course="${g.id}" data-loaded="0">
          <div class="acc-head">
            <div class="acc-left">
              <div class="acc-idx">${String(idx+1).padStart(2,'0')}</div>
              <div class="acc-title">${$('<div>').text(g.name).html()} Batches</div>
            </div>
            <div class="acc-status" aria-label="selected-indicator"></div>
          </div>
          <div class="acc-body" style="${idx === 0 ? '' : 'display:none;'}">
            <div class="p-3 text-muted text-center">Loading...</div>
          </div>
        </div>`;
    });

    $('#batchBoard').html(html);

    const $firstGroup = $('#batchBoard .acc-group').first();
    if ($firstGroup.length) {
      loadBatchGroup($firstGroup);
    }
  }).fail(function(){
    $('#batchBoard').html('<div class="p-3 text-danger text-center">Failed to load batch groups.</div>');
  });
}

// open/close accordion and lazy-load batches
function loadBatchGroup(wrap){
  const $wrap = $(wrap);
  const $body = $wrap.find('.acc-body');
  const cid = +$wrap.data('course');
  const loaded = +$wrap.attr('data-loaded') === 1;

  if (loaded) return;

  $.getJSON("../ajax/get_batches_by_course.php", { course_id: cid }, function(list){
    let inner = '';

    if (Array.isArray(list) && list.length){
      inner += `<div class="batch-grid">`;
      list.forEach(b => {
        const opt = $('<option>', { value:b.id, text:b.display_text });
        if ((+b.available_seats||0) <= 0) opt.prop("disabled", true);
        $("#batchSelect").append(opt);
        inner += renderBatchCard(b, cid);
      });
      inner += `</div>`;
    //} else {
    //  inner = `<div class="p-3 text-muted text-center">No open batches.</div>`;
    //}
} else {
  $wrap.remove();
  return;
}


    $body.html(inner);
    $wrap.attr('data-loaded','1');

    if (!multiBatchMode && !LOCK_BATCH_SELECTION) {
      const $firstCard = $body.find('.batch-card.pro').not('.locked').first();
      if ($firstCard.length) {
        selectBatchCard($firstCard, false);
      }
    }
  }).fail(function(xhr, status, err){
    const dump = xhr.responseText
      ? `<details class="mt-2"><summary class="text-muted">server response</summary><pre class="text-start small mb-0">${$('<div>').text(xhr.responseText).html()}</pre></details>`
      : '';
    $body.html(`<div class="p-3 text-danger text-center">Failed to load batches.<br><span class="small">${status}${err?': '+err:''}</span>${dump}</div>`);
  });
}

$(document).on('click', '.acc-head', function(){
  const $wrap = $(this).closest('.acc-group');
  const $body = $wrap.find('.acc-body');
  const isOpen = $wrap.hasClass('open');
  const loaded = +$wrap.attr('data-loaded') === 1;

  // anith groups close karanna
  $('.acc-group').not($wrap).removeClass('open').find('.acc-body').stop(true,true).slideUp(120);

  // meka already open nam -> close
  if (isOpen) {
    $wrap.removeClass('open');
    $body.stop(true,true).slideUp(120);
    return;
  }

  // නැත්නම් open
  $wrap.addClass('open');
  $body.stop(true,true).slideDown(120);

  if (!loaded) {
    loadBatchGroup($wrap);
  }
});

// NEW: click handler to select card
$(document).on('click', '.batch-card.pro', function(e){
  if (LOCK_BATCH_SELECTION || $(this).hasClass('locked') || $(this).data('locked') === 1) {
    e.preventDefault();
    return;
  }

  selectBatchCard($(this), true);
});

// Card renderer (shows batch_code + locks only FULL batches)
function renderBatchCard(b, courseId){
  const seats = +b.available_seats || Math.max(0, (+b.total_seat_count||0) - (+b.filled||0));
  const ok    = seats > 0;

  const mode   = (b.delivery_mode || 'WEEKDAY').toString().toUpperCase();
  const medium = ((b.medium_of_instruction || 'ENGLISH').toString().toUpperCase()) + ' MEDIUM';
  const top    = `${mode} / ${medium}`;

  const sub  = (b.display_text || b.batch_name || '').toString();

  // show code using several fallbacks
  const code = (b.batch_code || b.code || b.intake_name || b.batch_name || '')
    .toString().trim();

  const open  = (b.registration_open_date  || '').toString();
  const close = (b.registration_close_date || '').toString();
  const start = (b.batch_start_date        || '').toString();
  const end   = (b.batch_end_date          || '').toString();

  const safeAttr = s => String(s||'').replace(/"/g,'&quot;');
  const safeTxt  = s => String(s||'').replace(/[&<>"']/g, m => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[m]));

  // lock only when FULL, or when global lock is on
  const isLocked = (!ok) || LOCK_BATCH_SELECTION;
  const lockedCls  = isLocked ? ' locked' : '';
  const lockedData = isLocked ? ' data-locked="1"' : '';

  return `
  <div class="batch-card pro${lockedCls}"${lockedData}
       data-id="${safeAttr(b.id)}"
       data-course-id="${courseId}"
       data-branch-id="${safeAttr(b.branch_id||'')}"
       data-branch-name="${safeAttr(b.branch_name||'')}"
       data-open="${safeAttr(open)}"
       data-start="${safeAttr(start)}"
       data-close="${safeAttr(close)}"
       data-end="${safeAttr(end)}"
       data-label="${safeAttr(sub)}"
       title="${safeAttr(sub)}">
    <div class="bc-top">${safeTxt(top)}</div>
    <div class="bc-sub">${safeTxt(sub)}</div>
    <div class="bc-body">
      <div class="bc-seats">
        <div class="num">${seats}</div>
        <div class="lbl">Seats Available</div>
      </div>
      <div class="bc-details">
        <div class="bc-code">
          <span class="tag">${code ? safeTxt(code) : '—'}</span>
        </div>
        <div class="bc-date">
          <div class="d">${close ? safeTxt(close) : '-'}</div>
          <div class="lbl">Registration Closing Date</div>
        </div>
      </div>
    </div>
    <div class="bc-foot ${ok?'ok':'full'}">${ok?'SCHEDULED':'FULL'}</div>
  </div>`;
}

function renderBatchSchedule(meta){
  const fmtDate = s => {
    if (!s) return '';
    const d = new Date(s); return isNaN(d) ? s : d.toISOString().slice(0,10);
  };
  const relText = s => {
    if (!s) return '';
    const a=new Date(), b=new Date(s);
    if (isNaN(b)) return '';
    const d=Math.round((b-a)/86400000);
    if (d===0) return 'today';
    if (d>0)  return d>=7 ? (Math.round(d/7)+' weeks from now') : (d+' days from now');
    const dd=Math.abs(d);
    return dd>=7 ? (Math.round(dd/7)+' weeks ago') : (dd+' days ago');
  };
  const mkCls = s => {
    const x = s ? new Date(s) : null;
    return (!x || isNaN(x)) ? '' : (x <= new Date() ? 'done' : 'current');
  };

  const open  = fmtDate(meta.open);
  const start = fmtDate(meta.start);
  const close = fmtDate(meta.close);
  const end   = fmtDate(meta.end);

  const html = `
    <div class="notice mb-2">
      The batch might not be started if the minimum required headcount is not satisfied. In such an event,
      <ul class="mb-0 mt-2">
        <li>The batch might be extended maximum upto one month OR</li>
        <li>The students might be transferred to an ongoing batch after having a bridging session.</li>
      </ul>
    </div>

    <div class="tl">
      <div class="tl-grid">
        <div class="mil ${mkCls(open)}">
          <i class="bi bi-check-circle-fill ico"></i>
          <div class="lbl">Registration Opened</div>
          <div class="date">${open || '-'}</div>
        </div>
        <div class="mil ${mkCls(start)}">
          <i class="bi bi-check-circle-fill ico"></i>
          <div class="lbl">Batch Started</div>
          <div class="date">${start || '-'}</div>
        </div>
        <div class="mil ${mkCls(close)}">
          <i class="bi bi-question-circle-fill ico"></i>
          <div class="lbl">Registration Closing</div>
          <div class="date">${close || '-'}</div>
          ${close ? `<div class="mt-1"><span class="fromnow">${relText(close)}</span></div>` : ''}
        </div>
        <div class="mil ${mkCls(end)}">
          <i class="bi bi-question-circle-fill ico"></i>
          <div class="lbl">Batch Ending</div>
          <div class="date">${end || '-'}</div>
        </div>
      </div>
      <div class="tl-line"></div>
      <div class="mt-2 text-center muted">** Dates are not fixed and can be changed without prior notice</div>
    </div>
  `;
  $('#batchSchedulePane').html(html);
}

// ---------- STEP 4: Plans (DB-only discounts; robust course id resolution) ----------

let coursePresets = [];              // [{id, label, amount_lkr, is_default}]
let allInstallmentPlans = [];        // all plans (type='installment')
let currentInstallmentPlan = null;   // selected installment plan
let selectedPlan = null;             // one-time OR installment selection
let methodDiscPct = 0;               // cash/visa/amex % discount
let instSelectedDiscLkr = 0;         // chosen discount (LKR) for installment tab
let oneTimeSums = { cL:0, rL:0, cU:0, subL:0 };

const fmt = (n)=> Number(n||0).toLocaleString(undefined,{minimumFractionDigits:2,maximumFractionDigits:2});



function clearTotals(){
  $("#courseFeeLKR,#regFeeLKR,#subTotalLKR,#totalLKR,#methodDiscLKR,#discLKR,#planDiscLKR").text("0.00");
  $("#courseFeeUSD,#regFeeUSD,#certFeeUSD,#subTotalUSD,#totalUSD,#methodDiscUSD,#discUSD,#planDiscUSD").text("0.00");
}

function resolveCourseId(){
  let v = parseInt($("#selected_course_id").val() || $("#course_id").val() || 0, 10);
  if (v) return v;
  v = parseInt(($("#wizardRoot").data("courseId")) || 0, 10);
  if (v) return v;
  const qs = new URLSearchParams(location.search);
  v = parseInt(qs.get("course_id") || 0, 10);
  if (v) return v;
  v = parseInt(localStorage.getItem("ec.selected_course_id") || 0, 10);
  return isNaN(v) ? 0 : v;
}

function num(v){ const n = parseFloat(v); return isNaN(n) ? 0 : n; }

function sumPlan(plan){
  // header-level fallbacks (if API doesn't include installments)
  const hdrCL = num(plan?.course_fee_lkr ?? plan?.course_fee ?? plan?.course_fee_LKR);
  const hdrRL = num(plan?.registration_fee_lkr ?? plan?.registration_fee ?? plan?.reg_fee_lkr);
  const hdrCU = num(plan?.certificate_fee_usd ?? plan?.cert_fee_usd ?? plan?.certificate_fee);

  let cL = 0, rL = 0, cU = 0;

  const inst = Array.isArray(plan?.installments) ? plan.installments : [];

  if (inst.length){
    inst.forEach(x=>{
      cL += num(x?.course_fee_lkr ?? x?.course_fee);
      rL += num(x?.registration_fee_lkr ?? x?.registration_fee ?? x?.reg_fee_lkr);
      cU += num(x?.certificate_fee_usd ?? x?.cert_fee_usd);
    });

    // if installments don't carry cert fee but header does, use header once
    if (!cU && hdrCU) cU = hdrCU;
  } else {
    // no installments -> use header fees
    cL = hdrCL;
    rL = hdrRL;
    cU = hdrCU;
  }

  return { cL, rL, cU, subL: cL + rL };
}



// helper: does a plan set contain any positive-money installments?
function hasUsablePlans(plans){
  if (!Array.isArray(plans) || !plans.length) return false;
  for (const p of plans){
    const inst = (p && Array.isArray(p.installments)) ? p.installments : [];
    const sums = inst.reduce((a,x)=> {
      a.cL += parseFloat(x.course_fee_lkr||0);
      a.rL += parseFloat(x.registration_fee_lkr||0);
      a.cU += parseFloat(x.certificate_fee_usd||0);
      return a;
    }, {cL:0,rL:0,cU:0});
    if ((sums.cL + sums.rL + sums.cU) > 0) return true;
  }
  return false;
}

/* ---------- Plans loader (with bundle-children fallback) ---------- */

async function loadPlans(courseId){
  $("#oneTimeOptions").html('<div class="p-3 text-muted text-center">Loading…</div>');
  $("#installmentOptions").html('<div class="p-3 text-muted text-center">Loading…</div>');
  $("#instWrap").html('<div class="p-3 text-muted text-center">Select a plan to see installments.</div>');
  $("#payment-method-card").hide();
  selectedPlan = null; clearTotals();

  const jget = (url, data) => new Promise((res, rej)=>{
    $.getJSON(url, data).done(res).fail(rej);
  });

  try {
    let resp = await jget("../ajax/fetch_fee_plans.php", { course_id: courseId });

    let plans = Array.isArray(resp && resp.plans) ? resp.plans : [];
    let discounts = Array.isArray(resp && resp.discounts) ? resp.discounts : [];
    const base = resp && resp.base || null;

    // (optional) bundle children fallback you already have
    if (!hasUsablePlans(plans)) {
      try {
        const mod = await jget("../ajax/fetch_modules_from_courses.php", { course_id: courseId });
        const kids = Array.isArray(mod && mod.groups)
          ? mod.groups.map(g => +g.course_id || 0).filter(x => x>0 && x!==+courseId)
          : [];
        if (kids.length){
          let combined = [];
          let anyDiscounts = discounts;
          for (const kid of kids){
            try {
              const r = await jget("../ajax/fetch_fee_plans.php", { course_id: kid });
              if (Array.isArray(r && r.plans)) combined.push(...r.plans);
              if ((!anyDiscounts || !anyDiscounts.length) && Array.isArray(r && r.discounts)) anyDiscounts = r.discounts;
            } catch(e){}
          }
          if (hasUsablePlans(combined)) {
            plans = combined;
            discounts = anyDiscounts || [];
          }
        }
      } catch(e){}
    }

    coursePresets = Array.isArray(discounts) ? discounts : [];
    
    function recalculateTotals() {
  // ALWAYS USE STANDARD FEE VALUES (key fix)
  const standardCourseFee = parseFloat(oneTimeSums.cL || 0);
  const standardRegFee = parseFloat(oneTimeSums.rL || 0);
  const standardCertFee = parseFloat(oneTimeSums.cU || 0);
  const standardSubTotal = standardCourseFee + standardRegFee;
  
  // Calculate Plan Discount
  let planDiscount = 0;
  
  if (selectedPlan?.type === 'inst') {
    // For installment plans, use the selected discount amount
    planDiscount = parseFloat(instSelectedDiscLkr || 0);
  } else {
    // For one-time payment, use the preset discount
    planDiscount = parseFloat(selectedPlan?.preset_lkr || 0);
  }
  
  // Ensure discount doesn't exceed the standard course fee
  planDiscount = Math.min(planDiscount, standardCourseFee);
  
  // Manual Discount
  const manualDiscount = parseFloat($("#manual_discount_lkr").val() || 0);
  
  // Method Discount
  let methodDiscount = 0;
  if (methodDiscPct > 0) {
    const baseForMethod = standardSubTotal - planDiscount - manualDiscount;
    methodDiscount = (baseForMethod * methodDiscPct) / 100;
  }
  
  // Final Total
  const totalLKR = standardSubTotal - planDiscount - manualDiscount - methodDiscount;
  
  // Update UI
  $("#courseFeeLKR").text(currency(standardCourseFee));
  $("#regFeeLKR").text(currency(standardRegFee));
  $("#certFeeUSD").text(currency(standardCertFee));
  $("#subTotalLKR").text(currency(standardSubTotal));
  $("#planDiscLKR").text(currency(planDiscount));
  $("#discLKR").text(currency(manualDiscount));
  $("#methodDiscLKR").text(currency(methodDiscount));
  $("#totalLKR").text(currency(totalLKR));
  
  // Update payload with correct totals
  if (selectedPlan) selectedPlan.manual_discount_lkr = manualDiscount;
  persistSelectedPlanToHidden({
    course_fee_lkr: standardCourseFee,
    registration_fee_lkr: standardRegFee,
    certificate_fee_usd: standardCertFee,
    sub_total_lkr: standardSubTotal,
    plan_discount_lkr: planDiscount,
    manual_discount_lkr: manualDiscount,
    method_discount_lkr: methodDiscount,
    total_payable_lkr: totalLKR
  });
}


    // ---------- IMPORTANT FIX HERE ----------
    // Always build One-time base from STANDARD plan OR base fees
    const stdPlan = (plans || []).find(p => (p.type || '').toLowerCase() === 'standard');

    if (stdPlan) {
      oneTimeSums = sumPlan(stdPlan);  // ✅ Standard plan (68,900)
    } else if (base) {
      oneTimeSums = {
        cL: num(base.course_fee_lkr),
        rL: num(base.registration_fee_lkr),
        cU: num(base.certificate_fee_usd),
        subL: num(base.course_fee_lkr) + num(base.registration_fee_lkr)
      };
    } else {
      // last resort fallback: pick max from ALL plans (not only installment)
      const candidates = (plans || []).map(p => ({ plan:p, sums: sumPlan(p) }));
      oneTimeSums = candidates.length ? candidates.reduce((a,b)=> b.sums.subL > a.sums.subL ? b : a, candidates[0]).sums
                                      : { cL:0, rL:0, cU:0, subL:0 };
    }

    // Installments list remains the same
    allInstallmentPlans = (plans || []).filter(p =>
      (p.type||'').toLowerCase() === 'installment' &&
      Array.isArray(p.installments) && p.installments.length
    );
    currentInstallmentPlan = allInstallmentPlans[0] || null;

    renderOneTimePane(oneTimeSums);
    renderInstallmentPane(allInstallmentPlans);

    // Default should be One-time (optional)
    applyOneTimeSelection(0);

    $("#payment-method-card").slideDown(120);

  } catch (err) {
    $("#oneTimeOptions").html('<div class="p-3 text-danger text-center">Failed to load plans.</div>');
    $("#installmentOptions").html('<div class="p-3 text-danger text-center">Failed to load plans.</div>');
    console.warn('loadPlans error:', err);
  }
}


/* ------- One-time pane: Standard + every discount offer ------- */
// One-time pane rendering
function renderOneTimePane(sums){
  let html = `
    <label class="list-group-item d-flex justify-content-between align-items-center">
      <div>
        <div class="fw-semibold">Standard</div>
        <div class="small text-muted">Pay once in full</div>
      </div>
      <div class="text-end me-2">
        <div>LKR <b>${fmt(oneTimeSums.subL)}</b></div>
        ${oneTimeSums.cU ? `<div class="small text-muted">+ USD ${fmt(oneTimeSums.cU)}</div>` : ""}
      </div>
      <input type="radio" name="oneOpt" class="form-check-input ms-2" value="0" checked>
    </label>`;

  (coursePresets || []).forEach((d, idx)=>{
    const amt = Math.min(d.amount_lkr, oneTimeSums.cL);
    const net = Math.max(0, oneTimeSums.subL - amt);
    html += `
      <label class="list-group-item d-flex justify-content-between align-items-center">
        <div>
          <div class="fw-semibold">${d.label || ('Offer '+(idx+1))}</div>
          <div class="small text-muted">Auto minus LKR ${fmt(amt)}</div>
        </div>
        <div class="text-end me-2">
          <div>LKR <b>${fmt(net)}</b></div>
          ${oneTimeSums.cU ? `<div class="small text-muted">+ USD ${fmt(oneTimeSums.cU)}</div>` : ""}
        </div>
        <input type="radio" name="oneOpt" class="form-check-input ms-2" value="${amt}">
      </label>`;
  });
 


  $("#oneTimeOptions").html(html);

  $('#oneTimeOptions input[name="oneOpt"]').off('change').on('change', function(){
    applyOneTimeSelection(parseFloat(this.value || 0));
  });
}
function renderInstallmentPane(plans) {
  if (!plans.length) {
    $("#installmentOptions").html('<div class="p-3 text-danger text-center">No installment plans found.</div>');
    return;
  }

  let planList = '';
  plans.forEach((p, i) => {
    const sums = sumPlan(p);
    const standardFee = oneTimeSums.cL; // Standard course fee
    const standardReg = oneTimeSums.rL; // Standard registration fee
    const standardTotal = standardFee + standardReg;
    
    // Calculate the discount amount
    const discountAmount = standardTotal - sums.subL;
    
    planList += `
      <label class="list-group-item d-flex justify-content-between align-items-center">
        <div>
          <div class="fw-semibold">${p.plan_name || ('Plan '+(i+1))}</div>
          <div class="small text-muted">#Inst: ${(p.installments||[]).length} • ${p.duration_months ? (p.duration_months+' months') : '—'}</div>
        </div>
        <div class="text-end me-2">
          <div class="text-muted">Standard: LKR ${fmt(standardTotal)}</div>
          <div class="text-success">-${fmt(discountAmount)} discount</div>
          <div class="fw-bold">LKR <b>${fmt(sums.subL)}</b></div>
          ${sums.cU ? `<div class="small text-muted">+ USD ${fmt(sums.cU)}</div>` : ""}
        </div>
        <input type="radio" name="instPlan" class="form-check-input ms-2" value="${i}" ${i===0?'checked':''}>
      </label>`;
  });

  // Remove the discount options section entirely
  $("#installmentOptions").html(`
    <div class="list-group mb-2" id="instPlanList">${planList}</div>
  `);

  // default: first plan
  currentInstallmentPlan = plans[0];
  instSelectedDiscLkr = 0;
  applyInstallmentSelection(instSelectedDiscLkr, currentInstallmentPlan);

  $("#prefDueWrap").show();
  $("#preferred_due_day").val($("#prefDueDaySelect").val() || "");

  // handlers for plan selection only (no discount options anymore)
  $('#installmentOptions input[name="instPlan"]').off('change').on('change', function(){
    const idx = parseInt(this.value, 10) || 0;
    currentInstallmentPlan = allInstallmentPlans[idx] || allInstallmentPlans[0];
    applyInstallmentSelection(instSelectedDiscLkr, currentInstallmentPlan);
  });

 $('#installmentOptions input[name="instDisc"]').off('change').on('change', function(){
  instSelectedDiscLkr = parseFloat(this.value || 0);

  // ✅ Safety: if Standard selected → force 0
  if ($(this).closest('label').text().includes('Standard')) {
    instSelectedDiscLkr = 0;
  }

  applyInstallmentSelection(instSelectedDiscLkr, currentInstallmentPlan);
});
}
$("#btnApplyPrefDueDay").on("click", function(){
  if (!selectedPlan || selectedPlan.type !== 'inst') return;

  // Rebuild dates using current preferred day value
  selectedPlan.installments = normalizeInstallmentsWithAutoDates(selectedPlan.installments || []);
  renderInstallmentBreakdown(selectedPlan);
  persistSelectedPlanToHidden(); // keeps JSON updated
});

/* ------- Apply selections ------- */
function applyOneTimeSelection(discountAmountLkr){
  const sums = oneTimeSums;   // baseline from richest plan(s)
  const single = [{
    installment_no: 1,
    course_fee_lkr: sums.cL,
    registration_fee_lkr: sums.rL,
    certificate_fee_usd: sums.cU,
    due_date: ""
  }];

  selectedPlan = {
  type: 'one',
  plan_id: 'one-time',
  course_id: parseInt($("#course_id").val()||0,10),  // ✅ add
  installments: single,
  totals: { cL: sums.cL, rL: sums.rL, cU: sums.cU },
  plan_discount_lkr: Math.max(0, Number(discountAmountLkr||0)),
  name: discountAmountLkr > 0 ? 'One-time • Discount' : 'One-time • Standard'
};

  $("#fee_plan_id").val('one-time');
  $("#instWrap").html('<div class="p-3 text-muted text-center">One-time payment – no schedule to display.</div>');
  recalcTotals();
  persistSelectedPlanToHidden();
}

function applyInstallmentSelection(discountAmountLkr, plan){
  if (plan) currentInstallmentPlan = plan;
  const sums = sumPlan(currentInstallmentPlan || {installments:[]});

  let insts = normalizeInstallmentsWithAutoDates(currentInstallmentPlan?.installments || []);

  // ✅ If cert fee exists, show it on 1st row (and also send to backend)
  const cert = Number(sums.cU || 0);
  if (cert > 0) {
    const allZero = insts.every(x => Number(x.certificate_fee_usd||0) === 0);
    if (allZero && insts.length) insts[0].certificate_fee_usd = cert;
  }

selectedPlan = {
  type: 'inst',
  plan_id: currentInstallmentPlan?.id || 'installment',
  course_id: currentInstallmentPlan?.course_id || parseInt($("#course_id").val()||0,10),
  installments: insts,
  totals: { cL: sums.cL, rL: sums.rL, cU: sums.cU },
  plan_discount_lkr: Math.max(0, Number(discountAmountLkr||0)),
  manual_discount_lkr: Math.max(0, parseFloat($("#manual_discount_lkr").val()||0)),
  name: `Installments • ${(currentInstallmentPlan?.plan_name||'Plan')}${discountAmountLkr>0?' • Discount':''}`
};

  $("#fee_plan_id").val(selectedPlan.plan_id);
  renderInstallmentBreakdown(selectedPlan);
  recalcTotals();
  persistSelectedPlanToHidden();
} 

function renderInstallmentBreakdown(sel){
  if (!sel.installments || !sel.installments.length){
    $("#instWrap").html('<div class="p-3 text-muted text-center">No installments configured.</div>');
    return;
  }
  let sumCourse = 0, sumReg = 0, sumUSD = 0;
  sel.installments.forEach(inst=>{
    sumCourse += Number(inst.course_fee_lkr||0);
    sumReg    += Number(inst.registration_fee_lkr||0);
    sumUSD    += Number(inst.certificate_fee_usd||0);
  });

  let rows = `
    <table class="table table-tight table-striped m-0">
      <thead class="table-light">
        <tr>
          <th style="width:60px">#</th>
          <th>Course Fee (LKR)</th>
          <th>Reg Fee (LKR)</th>
          <th>Cert Fee (USD)</th>
          <th>Due Date</th>
        </tr>
      </thead>
      <tbody>`;
  sel.installments.forEach(inst=>{
    rows += `<tr>
      <td>${inst.installment_no||''}</td>
      <td class="text-end">${fmt(inst.course_fee_lkr)}</td>
      <td class="text-end">${fmt(inst.registration_fee_lkr)}</td>
      <td class="text-end">${fmt(inst.certificate_fee_usd)}</td>
      <td>${inst.due_date||''}</td>
    </tr>`;
  });

  // show discount line if any; USD unaffected
  const disc = Math.max(0, Number(sel.plan_discount_lkr||0));
  if (disc > 0){
    rows += `<tr class="table-warning">
      <td class="text-end text-muted">—</td>
      <td class="text-end text-danger">-${fmt(disc)}</td>
      <td class="text-end">0.00</td>
      <td class="text-end">0.00</td>
      <td class="text-muted">Plan Discount</td>
    </tr>`;
  }

  const netCourse = Math.max(0, sumCourse - disc);
  rows += `<tr class="table-light">
    <td class="text-end fw-semibold">Net</td>
    <td class="text-end fw-semibold">${fmt(netCourse)}</td>
    <td class="text-end fw-semibold">${fmt(sumReg)}</td>
    <td class="text-end fw-semibold">${fmt(sumUSD)}</td>
    <td></td>
  </tr>`;

  rows += `</tbody></table>`;
  $("#instWrap").html(rows);
}

/* ------- Totals + payload ------- */
function recalcTotals(){
  if (!selectedPlan){ clearTotals(); persistSelectedPlanToHidden({}); return; }

  const t = selectedPlan.totals || {cL:0,rL:0,cU:0};
  const subL = (t.cL||0) + (t.rL||0);
  const subU = (t.cU||0);
  const planDisc = Math.max(0, Number(selectedPlan.plan_discount_lkr||0));
  const manDisc  = Math.max(0, Number($("#manual_discount_lkr").val()||0));
  const baseForMethod = Math.max(0, subL - planDisc - manDisc);
  const methodDisc = baseForMethod * (methodDiscPct/100.0);
  const totalL = Math.max(0, subL - planDisc - manDisc - methodDisc);

  $("#courseFeeLKR").text(fmt(t.cL));
  $("#regFeeLKR").text(fmt(t.rL));
  $("#certFeeUSD").text(fmt(t.cU));
  $("#subTotalLKR").text(fmt(subL));
  $("#subTotalUSD").text(fmt(subU));
  $("#planDiscLKR").text(fmt(planDisc)); $("#planDiscUSD").text("0.00");
  $("#discLKR").text(fmt(manDisc));       $("#discUSD").text("0.00");
  $("#methodDiscLKR").text(fmt(methodDisc)); $("#methodDiscUSD").text("0.00");
  $("#totalLKR").text(fmt(totalL));
  $("#totalUSD").text(fmt(subU));

 if (selectedPlan) selectedPlan.manual_discount_lkr = manDisc;
 
  persistSelectedPlanToHidden({
    course_fee_lkr: t.cL,
    registration_fee_lkr: t.rL,
    certificate_fee_usd: t.cU,
    sub_total_lkr: subL,
    plan_discount_lkr: planDisc,
    manual_discount_lkr: manDisc,
    method_discount_lkr: methodDisc,
    total_payable_lkr: totalL
  });
}

function persistSelectedPlanToHidden(extraTotals){
  try{
    const payload = {
  type: selectedPlan?.type || null,
  plan_id: selectedPlan?.plan_id ?? null,
  course_id: selectedPlan?.course_id ?? null, // ✅ add
  plan_name: selectedPlan?.name || '',
  totals: selectedPlan?.totals || {cL:0,rL:0,cU:0},
  installments: selectedPlan?.installments || [],
  plan_discount_lkr: +(selectedPlan?.plan_discount_lkr||0),
  manual_discount_lkr: +(document.getElementById('manual_discount_lkr')?.value || 0),
  method: document.getElementById('discount_method')?.value || '',
  computed: extraTotals || {}
};
document.getElementById('selected_plan_json').value = JSON.stringify(payload);
  }catch(e){ /* ignore */ }
}
/* Payment method % radios */
$(".dm-radio").on("change", function(){
  const v = $(this).val();
  $("#discount_method").val(v);
  methodDiscPct = (v==='cash')?10 : (v==='card_visa'?7.5 : (v==='amex'?7:0));
  recalcTotals();
});

/* Manual discount button */
$("#btnManualDiscount").on("click", function(){
  const cur = parseFloat($("#manual_discount_lkr").val()||0);
  const v = prompt("Manual discount in LKR:", isNaN(cur)?0:cur);
  if (v===null) return;
  $("#manual_discount_lkr").val(Math.max(0, parseFloat(v)||0));
  recalcTotals();
});

/* ---- Bootstrap this step on load or when course changes ---- */
$(function(){
  const cid = resolveCourseId();
  if (cid) loadPlans(cid);
  else $("#oneTimeOptions, #installmentOptions").html('<div class="p-3 text-muted text-center">Select a course to view options.</div>');

  window.addEventListener('course:selected', (e)=>{
    const id = parseInt(e.detail?.course_id || 0, 10);
    if (id){ localStorage.setItem('ec.selected_course_id', id); loadPlans(id); }
  });
});


  // ---------- Step 5: Existing student search ----------
  let srTimer=null;
  $("#studentSearch").on("input", function(){
    const q = $(this).val().trim();
    clearTimeout(srTimer);
    if (q.length < 2) { $("#studentResults").addClass("d-none").empty(); return; }
    srTimer = setTimeout(()=>{
      $.getJSON("../ajax/search_students.php", { q }, function(rows){
        const box = $("#studentResults").empty();
        if (!rows || !rows.length){ box.append('<div class="text-muted">No matches.</div>'); }
        else {
          rows.forEach(r=>{
            box.append(`<div data-json='${JSON.stringify(r)}'>
              <div class="fw-semibold">${escapeHtml(r.full_name||'Unknown')}</div>
              <div class="small text-muted">Reg: ${escapeHtml(r.reg_no||'-')} • NIC: ${escapeHtml(r.nic||'-')}</div>
            </div>`);
          });
        }
        box.removeClass("d-none");
      });
    }, 220);
  });
$("#studentResults").on("click", "div", function(){
  const r = JSON.parse($(this).attr("data-json") || "{}");

  $("#existing_student_id").val(r.id || 0);
  $("#studentSearch").val(r.reg_no || r.center_reg_no || r.reference_no || r.full_name || '');
  $("#studentResults").addClass("d-none").empty();

  const el = document.getElementById('step-student');
  if (el) bootstrap.Collapse.getOrCreateInstance(el, {toggle:false}).show();

  // Personal Information
  $("#st_title").val(r.title || '');
  $("#st_full_name, input[name='full_name']").val(r.full_name || '');
  $("#st_gender, select[name='gender']").val(r.gender || '');
  $("input[name='dob']").val(r.dob || '');
  $("#st_nationality").val(r.nationality || '');
  $("#st_nic, input[name='nic']").val(r.nic || r.nic_passport || '');

  // Contact Information
  $("#st_mobile, input[name='mobile']").val(r.mobile || '');
  $("input[name='email']").val(r.email || '');
  $("input[name='address1']").val(r.address1 || '');
  $("input[name='address2']").val(r.address2 || '');
  $("input[name='city']").val(r.city || '');
  $("input[name='country']").val(r.country || '');

  // Guardian Information
  $("input[name='guardian_name']").val(r.guardian_name || '');
  $("input[name='guardian_relationship']").val(r.guardian_relationship || '');
  $("input[name='guardian_contact']").val(r.guardian_contact || '');

  $("#btnAddStudent").text("Hide Student Form");
  $("#step5 .is-invalid").removeClass("is-invalid");

  updateConfirmButtonState();
});
  $("#btnClearStudent").on("click", function(){
    $("#existing_student_id").val(0);
    $("#studentSearch").val('');
    $("#studentResults").addClass("d-none").empty();
  });

  // Toggle button text on collapse show/hide
  const stEl = document.getElementById('step-student');
  if (stEl) {
    stEl.addEventListener('shown.bs.collapse', () => { $('#btnAddStudent').text('Hide Student Form'); });
    stEl.addEventListener('hidden.bs.collapse', () => { $('#btnAddStudent').text('+ Add Student'); });
  }

  // ---------- REQUIRED STUDENT FIELDS VALIDATION ----------
  function getStudentVals(){
  return {
    full_name: ($("#st_full_name").val() || $("input[name='full_name']").val() || "").trim(),
    gender:    ($("#st_gender").val() || $("select[name='gender']").val() || "").trim(),
    mobile:    ($("#st_mobile").val() || $("input[name='mobile']").val() || "").trim()
    // NIC intentionally omitted from required set
  };
}
  function markInvalidFields(v){
  $("#st_full_name, input[name='full_name']").toggleClass("is-invalid", !v.full_name);
  $("#st_gender, select[name='gender']").toggleClass("is-invalid", !v.gender);
  $("#st_mobile, input[name='mobile']").toggleClass("is-invalid", !v.mobile);
  // no NIC invalid toggle anymore
}
  function validateStudent(showAlert){
  const v = getStudentVals();
  const missing = [];
  if (!v.full_name) missing.push("Student Name");
  if (!v.gender)    missing.push("Gender");
  if (!v.mobile)    missing.push("Mobile Number");
  markInvalidFields(v);
  if (missing.length && showAlert){
    alert("Please complete the required fields:\n- " + missing.join("\n- "));
  }
  return missing.length === 0;
}
  function updateConfirmButtonState(){
    const ok = validateStudent(false);
    $("#btnConfirmRegister").prop("disabled", !ok);
  }
  // Live updates while typing/changing
 $(document).on("input change", "#st_full_name, #st_gender, #st_mobile, input[name='full_name'], select[name='gender'], input[name='mobile']", function(){
  updateConfirmButtonState();
});
  // Step 6: Confirm
  function buildConfirm(){
    $("#cConfirm").text(selectedCourseName||'-');
    $("#mConfirm").text(modulesCache.join(', ') || '-');

    const bTexts = $('.batch-card.selected').map(function(){
      return $(this).data('label') || $(this).attr('title') || ('Batch '+$(this).data('id'));
    }).get();
    $("#bConfirm").text(bTexts.length ? bTexts.join(' • ') : '-');

    $("#pConfirm").text(selectedPlan ? (selectedPlan.name || 'Plan') : '-');
    $("#tConfirm").text(`LKR ${$("#totalLKR").text() || '0.00'} • USD ${$("#totalUSD").text() || '0.00'}`);


    const sName   = $("input[name='full_name']").val() || '-';
    const sMobile = $("input[name='mobile']").val()    || '-';
    const sNic    = $("input[name='nic']").val()       || '-';
    $("#sConfirm").text(`${sName} • ${sMobile} • ${sNic}`);
  }
  
  // --- Tab handlers (must be inside the same IIFE so functions exist) ---
$('#onetab').on('shown.bs.tab', function(){
  applyOneTimeSelection(parseFloat($('#oneTimeOptions input[name="oneOpt"]:checked').val() || 0));
  $("#prefDueWrap").hide();
});

$('#instab').on('shown.bs.tab', function(){
  if (currentInstallmentPlan) applyInstallmentSelection(instSelectedDiscLkr, currentInstallmentPlan);
  $("#prefDueWrap").show();
});

})();

</script>
<script>
// ===== Installment date generator (UI preview + payload) =====
function pad2(n){ return String(n).padStart(2,'0'); }

function todayYmd(){
  const d = new Date();
  return `${d.getFullYear()}-${pad2(d.getMonth()+1)}-${pad2(d.getDate())}`;
}

// Preserves day-of-month; clamps to month end (Jan 31 -> Feb 28/29)
function addMonthsPreserveDom(startYmd, addMonths){
  const parts = (startYmd || '').split('-').map(x=>parseInt(x,10));
  let Y = parts[0] || new Date().getFullYear();
  let M = parts[1] || (new Date().getMonth()+1);
  let D = parts[2] || new Date().getDate();

  let y = Y;
  let m = M + addMonths;

  y += Math.floor((m - 1) / 12);
  m  = ((m - 1) % 12) + 1;

  const lastDay = new Date(y, m, 0).getDate();
  const day = Math.min(D, lastDay);

  return `${y}-${pad2(m)}-${pad2(day)}`;
}

function addDaysYmd(ymd, days){
  const [y,m,d] = (ymd||todayYmd()).split('-').map(n=>parseInt(n,10));
  const dt = new Date(y, (m||1)-1, d||1);
  dt.setDate(dt.getDate() + (days||0));
  return `${dt.getFullYear()}-${pad2(dt.getMonth()+1)}-${pad2(dt.getDate())}`;
}

// Create date in target month using a preferred day; clamp to month-end
function makeMonthlyDue(firstDueYmd, monthsAfter, preferredDay){
  const [y,m,d] = firstDueYmd.split('-').map(n=>parseInt(n,10));
  const base = new Date(y, m-1, 1);
  base.setMonth(base.getMonth() + monthsAfter);

  const yy = base.getFullYear();
  const mm = base.getMonth()+1;
  const last = new Date(yy, mm, 0).getDate();

  const dayWanted = preferredDay ? parseInt(preferredDay,10) : d; // fallback to firstDue DOM
  const dd = Math.min(Math.max(dayWanted,1), last);

  return `${yy}-${pad2(mm)}-${pad2(dd)}`;
}

/**
 * RULE:
 * - inst #1 = regDate + 5 days
 * - inst #2..N = monthly cycle using preferred day (or fallback to inst#1 day)
 */
function normalizeInstallmentsWithAutoDates(installments){
  const regDate = todayYmd();                 // registration date (today)
  const firstDue = addDaysYmd(regDate, 5);    // +5 days

  const pref = document.getElementById('prefDueDaySelect')?.value || '';
  document.getElementById('preferred_due_day').value = pref; // send to PHP

  const arr = (installments || []).map((inst,i)=> {
    const no = i + 1;

    let due = '';
    if (no === 1) {
      due = firstDue;
    } else {
      // month offsets: #2 => +1 month, #3 => +2 months ...
      due = makeMonthlyDue(firstDue, no-1, pref);
    }

    return {
      ...inst,
      installment_no: no,
      due_date: due
    };
  });

  return arr;
}
</script>


</main>
<?php include __DIR__ . '/../includes/footer.php'; ?>
</body>
</html>