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

// allow if user has either view OR manage
if (!ec_can('batches.view') && !ec_can('batches.manage')) {
  header('Location: /edenrms/pages/403.php'); exit;
}

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
include __DIR__ . '/../includes/db.php';
if (!isset($conn) || !($conn instanceof mysqli)) { die('DB not connected'); }
$conn->set_charset('utf8mb4');

/* ------------ bundle-aware helpers (schema-aligned) ------------ */
function is_bundle_course(mysqli $c, int $course_id): bool {
  $st = $c->prepare("SELECT 1 FROM course_children WHERE parent_id=? LIMIT 1");
  $st->bind_param('i', $course_id);
  $st->execute();
  $ok = (bool)$st->get_result()->fetch_column();
  $st->close();
  return $ok;
}

function ensure_batch_modules_table(mysqli $c): void {
  $c->query("CREATE TABLE IF NOT EXISTS batch_modules (
              id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
              batch_id INT(10) UNSIGNED NOT NULL,
              course_module_id INT(10) UNSIGNED NOT NULL,
              source_course_id INT(10) UNSIGNED NULL,
              created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
              UNIQUE KEY uniq_batch_mod (batch_id, course_module_id),
              KEY idx_batch (batch_id),
              KEY idx_mod (course_module_id)
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4");
}

/** Return DISTINCT course_module ids (with their source child course) for a bundle */
function bundle_course_modules(mysqli $c, int $bundle_course_id): array {
  $sql = "SELECT DISTINCT cm.id AS course_module_id, cm.course_id AS source_course_id
          FROM course_children bc
          JOIN course_modules cm ON cm.course_id = bc.child_id
          WHERE bc.parent_id = ?";
  $st = $c->prepare($sql);
  $st->bind_param('i', $bundle_course_id);
  $st->execute();
  $rows = $st->get_result()->fetch_all(MYSQLI_ASSOC);
  $st->close();
  return array_map(fn($r)=>[(int)$r['course_module_id'], (int)$r['source_course_id']], $rows);
}

/** Insert IGNORE the unioned modules into batch_modules for this bundle batch */
function sync_bundle_modules_into_batch(mysqli $c, int $batch_id, int $bundle_course_id): void {
  ensure_batch_modules_table($c);
  $pairs = bundle_course_modules($c, $bundle_course_id);
  if (!$pairs) return;

  $values = [];
  $types  = '';
  $bind   = [];
  foreach ($pairs as [$cmid, $src]) {
    $values[] = "(?,?,?)";
    $types .= 'iii';
    $bind[] = $batch_id; $bind[] = $cmid; $bind[] = $src ?: null;
  }
  $sql = "INSERT IGNORE INTO batch_modules (batch_id, course_module_id, source_course_id)
          VALUES ".implode(',', $values);
  $st = $c->prepare($sql);
  $st->bind_param($types, ...$bind);
  $st->execute();
  $st->close();
}

/** Enroll existing bundle students into a target batch (no duplicates) */
function propagate_bundle_enrollments(mysqli $c, int $bundle_course_id, int $target_batch_id): void {
  $q = $c->prepare("SELECT DISTINCT e.student_id
                    FROM enrollments e
                    JOIN batches b ON b.id = e.batch_id
                    WHERE b.course_id = ? AND b.id <> ?");
  $q->bind_param('ii', $bundle_course_id, $target_batch_id);
  $q->execute();
  $rs = $q->get_result();
  $ins = $c->prepare("INSERT INTO enrollments (batch_id, student_id, enrollment_date)
                      SELECT ?, ?, CURDATE()
                      WHERE NOT EXISTS (SELECT 1 FROM enrollments WHERE batch_id=? AND student_id=?)");
  while ($row = $rs->fetch_assoc()) {
    $sid = (int)$row['student_id'];
    $ins->bind_param('iiii', $target_batch_id, $sid, $target_batch_id, $sid);
    $ins->execute();
  }
  $ins->close(); $q->close();
}

/* ---------------- helpers ---------------- */
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, 'UTF-8'); }

/* INFORMATION_SCHEMA works with prepared statements */
function texists(mysqli $c, string $name): bool {
  $sql = "SELECT 1 FROM INFORMATION_SCHEMA.TABLES
          WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? LIMIT 1";
  $st = $c->prepare($sql);
  $st->bind_param('s',$name);
  $st->execute();
  $ok = $st->get_result()->num_rows > 0;
  $st->close();
  return $ok;
}

$action = $_POST['action'] ?? $_GET['action'] ?? null;
auto_inactivate_expired_batches($conn);

/* COLUMN exists helper */
function cexists(mysqli $c, string $table, string $col): bool {
  $sql = "SELECT 1
            FROM INFORMATION_SCHEMA.COLUMNS
           WHERE TABLE_SCHEMA = DATABASE()
             AND TABLE_NAME = ?
             AND COLUMN_NAME = ?
           LIMIT 1";
  $st = $c->prepare($sql);
  $st->bind_param('ss', $table, $col);
  $st->execute();
  $ok = $st->get_result()->num_rows > 0;
  $st->close();
  return $ok;
}

function auto_inactivate_expired_batches(mysqli $c): void {
  $c->query("
    UPDATE batches
    SET status = 'Inactive'
    WHERE batch_end_date IS NOT NULL
      AND batch_end_date <> '0000-00-00'
      AND batch_end_date < CURDATE()
      AND status = 'Active'
  ");
}
/* ---------- Persist canonical batch tag ---------- */
function ensure_batch_code_column(mysqli $c): void {
  if (!cexists($c,'batches','batch_code')) {
    $c->query("ALTER TABLE batches
               ADD COLUMN batch_code VARCHAR(100) NULL AFTER batch_name,
               ADD INDEX idx_batch_code (batch_code)");
  }
}

/** Build code like DIP/MON/ENG/B-12 (no parentheses) */
function compute_batch_code(string $batch_name, ?string $medium, int $id, ?string $batch_no): string {
  $base = trim($batch_name ?? '');
  if (preg_match('/\((.*?)\)/', $base, $m)) { $base = trim($m[1]); }

  $medAbbr   = medium_abbrev($medium ?? '');
  $hasMedium = $base !== '' && preg_match('/(?:^|\/)(sin|eng|tam|sinhala|english|tamil)(?:\/|$)/i', $base);
  if ($base !== '' && !$hasMedium && $medAbbr !== '') $base .= '/' . $medAbbr;

  $bn = display_batch_no($id, $batch_no);
  if ($base === '') return $bn;
  if (preg_match('/\/B-\d+$/i', $base)) return $base; // already ends with B-##
  return $base . '/' . $bn;
}

/** Read row -> compute -> save to batches.batch_code */
function update_batch_code(mysqli $c, int $id): void {
  // make sure the column exists
  ensure_batch_code_column($c);

  $hasBatchNo = cexists($c,'batches','batch_no');
  $sel = "SELECT batch_name, medium_of_instruction, "
       . ($hasBatchNo ? "batch_no" : "NULL") . " AS batch_no
         FROM batches WHERE id=?";
  $st = $c->prepare($sel);
  $st->bind_param('i', $id);
  $st->execute();
  $row = $st->get_result()->fetch_assoc();
  $st->close();
  if (!$row) return;

  $code = compute_batch_code(
    (string)$row['batch_name'],
    $row['medium_of_instruction'] ?? '',
    $id,
    $row['batch_no'] ?? null
  );

  $up = $c->prepare("UPDATE batches SET batch_code=? WHERE id=?");
  $up->bind_param('si', $code, $id);
  $up->execute();
  $up->close();
}

/**
 * Make a batch number using row ID; preserve existing prefix/width if any sample exists.
 * Fallback prefix: "B-".
 */
function ec_make_batch_no(mysqli $c, int $id): string {
  $prefix = 'B-';
  $width  = 0;
  try {
    $st = $c->prepare("SELECT batch_no FROM batches WHERE batch_no IS NOT NULL AND batch_no<>'' ORDER BY id DESC LIMIT 1");
    $st->execute();
    $st->bind_result($sample);
    if ($st->fetch() && $sample) {
      if (preg_match('/(\d+)$/', $sample, $m)) {
        $width  = strlen($m[1]);
        $prefix = substr($sample, 0, -$width);
      } else {
        $prefix = $sample;
      }
    }
    $st->close();
  } catch (Throwable $e) { /* ignore */ }

  $num = (string)$id;
  if ($width > 0) $num = str_pad($num, $width, '0', STR_PAD_LEFT);
  return $prefix . $num;
}

/** Pretty batch number for display; keeps existing prefix/width; else "B-<ID>" (2 digits). */
function display_batch_no(int $id, ?string $batch_no): string {
  $bn = trim((string)$batch_no);
  if ($bn !== '') {
    if (preg_match('/^(.+?)(\d+)$/', $bn, $m)) {
      return $m[1] . str_pad($m[2], 2, '0', STR_PAD_LEFT);
    }
    return $bn;
  }
  return 'B-' . str_pad((string)$id, 2, '0', STR_PAD_LEFT);
}
/** 'Sinhala' -> 'Sin', 'English' -> 'Eng', 'Tamil' -> 'Tam' (default = first 3 letters) */
function medium_abbrev(?string $s): string {
  $s = strtolower(trim((string)$s));
  switch ($s) {
    case 'sinhala': return 'Sin';
    case 'english': return 'Eng';
    case 'tamil':   return 'Tam';
    default:        return $s !== '' ? ucfirst(substr($s, 0, 3)) : '';
  }
}
/* ---------------- AJAX: main table ---------------- */
if ($action === 'fetch') {
  $more = '';
  if (cexists($conn,'batches','batch_no'))   $more .= ', b.batch_no';
  if (cexists($conn,'batches','batch_code')) $more .= ', b.batch_code';

  $sql = "
    SELECT
      b.id, b.batch_name, b.course_id, b.delivery_mode, b.medium_of_instruction,
      b.registration_open_date, b.registration_close_date,
      b.batch_start_date, b.batch_end_date, b.total_seat_count, b.status,
      co.course_name
      {$more},
      COALESCE(cnt.filled,0) AS filled
    FROM batches b
    JOIN courses co ON co.id=b.course_id
    LEFT JOIN (
      SELECT batch_id, COUNT(*) AS filled
      FROM enrollments
      GROUP BY batch_id
    ) cnt ON cnt.batch_id=b.id
    ORDER BY b.id DESC";
  $rs = $conn->query($sql);

  echo '<div class="table-responsive">';
  echo '<table id="batchesTable" class="table table-hover align-middle w-100">';
  echo '
  <thead>
    <tr class="table-light">
      <th rowspan="2" class="align-middle">Status</th>
      <th rowspan="2" class="align-middle">Batch Name <span class="text-muted">/ ID</span></th>
      <th rowspan="2" class="align-middle">Course <span class="text-muted">/ Delivery Mode</span></th>
      <th rowspan="2" class="align-middle">Date Start</th>
      <th rowspan="2" class="align-middle">Date End</th>
      <th colspan="3" class="text-center">Seats</th>
      <th rowspan="2" class="align-middle">Action</th>
    </tr>
    <tr class="table-light">
      <th class="text-center">Total</th>
      <th class="text-center">Filled</th>
      <th class="text-center">Available</th>
    </tr>
  </thead>
  <tbody>';

  while ($r = $rs->fetch_assoc()) {
    $id     = (int)$r['id'];
    $status = ($r['status'] === 'Active')
          ? '<span class="batch-status-badge batch-status-active">Active</span>'
          : '<span class="batch-status-badge batch-status-inactive">Inactive</span>';

    $total  = (int)$r['total_seat_count'];
    $filled = (int)$r['filled'];
    $avail  = max(0, $total - $filled);
    $availHtml = $avail<=5 ? "<span class='text-danger fw-semibold'>$avail</span>" : $avail;

    // Prefer persisted batch_code; fallback to compute
    $bn = display_batch_no($id, $r['batch_no'] ?? null);
    $tagText = trim((string)($r['batch_code'] ?? ''));

    if ($tagText === '') {
      $base = trim((string)($r['batch_name'] ?? ''));
      if (preg_match('/\((.*?)\)/', $base, $m)) $base = trim($m[1]);
      $medAbbr = medium_abbrev($r['medium_of_instruction'] ?? '');
      $hasMedium = $base !== '' && preg_match('/(?:^|\/)(sin|eng|tam|sinhala|english|tamil)(?:\/|$)/i', $base);
      if ($base !== '' && !$hasMedium && $medAbbr !== '') $base .= '/' . $medAbbr;
      if     ($base === '')                      $tagText = $bn;
      elseif (preg_match('/\/B-\d+$/i', $base))  $tagText = $base;
      else                                       $tagText = $base . '/' . $bn;
    }
    $tag = ' <span class="text-muted small">(' . h($tagText) . ')</span>';

    echo "<tr>";
    echo "<td>{$status}</td>";
    echo "<td><div class='fw-semibold'>".h($r['batch_name'])."{$tag}</div><div class='small text-muted'>#{$id}</div></td>";
    echo "<td><div>".h($r['course_name'])."</div><div class='small text-muted'>".h($r['delivery_mode'] ?: 'N/A')."</div></td>";
    echo "<td>".h($r['batch_start_date'] ? date('Y-m-d',strtotime($r['batch_start_date'])) : 'N/A')."</td>";
    echo "<td>".h($r['batch_end_date']   ? date('Y-m-d',strtotime($r['batch_end_date']))   : 'N/A')."</td>";
    echo "<td class='text-center'>{$total}</td>";
    echo "<td class='text-center'>{$filled}</td>";
    echo "<td class='text-center'>{$availHtml}</td>";
    echo "<td><button class='btn btn-sm btn-primary batch-manage-btn' onclick='openManage({$id})'>Manage</button></td>";
    echo "</tr>";
  }

  echo '</tbody></table></div>';
  exit;
}

/* ---------------- AJAX: overview data ---------------- */
if ($action === 'view') {
  $id = (int)($_GET['id'] ?? 0);
  $sql = "
    SELECT b.*, co.course_name,
           COALESCE(cnt.filled,0) AS filled
    FROM batches b
    JOIN courses co ON co.id=b.course_id
    LEFT JOIN (SELECT batch_id, COUNT(*) AS filled FROM enrollments GROUP BY batch_id) cnt
      ON cnt.batch_id=b.id
    WHERE b.id=? LIMIT 1";
  $st=$conn->prepare($sql);
  $st->bind_param('i',$id);
  $st->execute();
  $row = $st->get_result()->fetch_assoc();
  $st->close();
  if (!$row){ http_response_code(404); echo json_encode(['error'=>'Not found']); exit; }

  $total = (int)$row['total_seat_count'];
  $filled= (int)$row['filled'];
  $avail = max(0,$total-$filled);

  echo json_encode([
    'id'=>(int)$row['id'],
    'batch_name'=>$row['batch_name'],
    'course_name'=>$row['course_name'],
    'delivery_mode'=>$row['delivery_mode'],
    'medium_of_instruction'=>$row['medium_of_instruction'],
    'registration_open_date'=>$row['registration_open_date'],
    'registration_close_date'=>$row['registration_close_date'],
    'batch_start_date'=>$row['batch_start_date'],
    'batch_end_date'=>$row['batch_end_date'],
    'description'=>$row['description'],
    'status'=>$row['status'],
    'seats'=>['total'=>$total,'filled'=>$filled,'available'=>$avail]
  ]);
  exit;
}

/* -------------- AJAX: students list (strict batch filter) -------------- */
if ($action === 'students') {
  $batchId = (int)($_GET['id'] ?? 0);

  // seats
  $seatQ = $conn->prepare("
    SELECT total_seat_count AS total,
           COALESCE(cnt.filled,0) AS filled
    FROM batches b
    LEFT JOIN (SELECT batch_id, COUNT(*) filled FROM enrollments GROUP BY batch_id) cnt
      ON cnt.batch_id=b.id
    WHERE b.id=?");
  $seatQ->bind_param('i',$batchId);
  $seatQ->execute();
  $srow = $seatQ->get_result()->fetch_assoc();
  $seatQ->close();
  $available = max(0, (int)($srow['total']??0) - (int)($srow['filled']??0));

  $sql = "
    SELECT
      e.id,
      s.id          AS student_id,
      s.center_reg_no,
      s.reference_no,
      s.full_name,
      s.mobile,
      s.email,
      e.enrollment_date
    FROM enrollments e
    JOIN studentss s ON s.id = e.student_id
    WHERE e.batch_id = ?
    ORDER BY e.id DESC";
  $st = $conn->prepare($sql);
  $st->bind_param('i',$batchId);
  $st->execute();
  $res = $st->get_result();

/* >>> PLACE THESE TWO LINES HERE <<< */
ensure_batch_code_column($conn);
update_batch_code($conn, $batchId);

  $rows=[];
  while($r=$res->fetch_assoc()){
    $regId = $r['center_reg_no'] ?: $r['reference_no'];
    $rows[] = [
      'payment' => '-',
      'registration_id' => (string)$regId,
      'student_id' => (string)$r['student_id'],
      'available_seat' => $available,
      'name' => (string)$r['full_name'],
      'mobile' => (string)$r['mobile'],
      'email' => (string)$r['email'],
      'registered_at' => $r['enrollment_date'] ? date('Y-m-d', strtotime($r['enrollment_date'])) : ''
    ];
  }
  $st->close();

  echo json_encode(['rows'=>$rows,'available'=>$available]);
  exit;
}

/* ---------------- AJAX: get one (edit) ---------------- */
if ($action === 'get') {
  $id = (int)($_GET['id'] ?? 0);
  $st=$conn->prepare("SELECT * FROM batches WHERE id=?");
  $st->bind_param('i',$id); $st->execute();
  echo json_encode($st->get_result()->fetch_assoc() ?: []);
  $st->close(); exit;
}

/* ---------------- AJAX: add/update (bundle-aware) ---------------- */
if ($action === 'add' || $action === 'update') {
  $id = (int)($_POST['batch_id'] ?? 0);
  $batch_name = $_POST['batch_name'] ?? '';
  $course_id  = (int)($_POST['course_id'] ?? 0);
  $delivery_mode = $_POST['delivery_mode'] ?? '';
  $medium_of_instruction = $_POST['medium_of_instruction'] ?? '';
  $is_enforced = (int)($_POST['is_enforced'] ?? 0);

  // these are NOT NULL in your schema – enforce presence
  $registration_open_date  = $_POST['registration_open_date']  ?? '';
  $registration_close_date = $_POST['registration_close_date'] ?? '';
  $batch_start_date        = $_POST['batch_start_date']        ?? '';
  $batch_end_date          = $_POST['batch_end_date']          ?? '';

  $total_seat_count = (int)($_POST['total_seat_count'] ?? 0);
  $description = $_POST['description'] ?? '';
  $status = $_POST['status'] ?? 'Inactive';

  if ($action === 'add') {
    $sql = "INSERT INTO batches
            (batch_name, course_id, delivery_mode, medium_of_instruction, is_enforced,
             registration_open_date, registration_close_date, batch_start_date, batch_end_date,
             total_seat_count, description, status)
            VALUES (?,?,?,?,?,?,?,?,?,?,?,?)";
    $st=$conn->prepare($sql);
    $st->bind_param(
      'sississssiss',
      $batch_name,
      $course_id,
      $delivery_mode,
      $medium_of_instruction,
      $is_enforced,
      $registration_open_date,
      $registration_close_date,
      $batch_start_date,
      $batch_end_date,
      $total_seat_count,
      $description,
      $status
    );
    $st->execute();
    $st->close();

    $batchId = (int)$conn->insert_id;

    // Auto-generate batch number if the column exists and is empty
    if (cexists($conn, 'batches', 'batch_no')) {
      $bn = ec_make_batch_no($conn, $batchId);
      $up = $conn->prepare("UPDATE batches SET batch_no=? WHERE id=? AND (batch_no IS NULL OR batch_no='')");
      $up->bind_param('si', $bn, $batchId);
      $up->execute();
      $up->close();
    }

/* >>> PLACE THESE TWO LINES HERE <<< */
ensure_batch_code_column($conn);
update_batch_code($conn, $batchId);

    if (is_bundle_course($conn, $course_id)) {
      // 1) union child modules into this batch
      sync_bundle_modules_into_batch($conn, $batchId, $course_id);
      // 2) enroll all existing bundle students into this new batch (toggle via is_enforced)
      if ($is_enforced === 1) {
        propagate_bundle_enrollments($conn, $course_id, $batchId);
      }
    }

    echo "OK"; exit;

  } else { // update
    $sql = "UPDATE batches SET
              batch_name=?, course_id=?, delivery_mode=?, medium_of_instruction=?, is_enforced=?,
              registration_open_date=?, registration_close_date=?, batch_start_date=?, batch_end_date=?,
              total_seat_count=?, description=?, status=?
            WHERE id=?";
    $st=$conn->prepare($sql);
    $st->bind_param(
      'sississssissi',
      $batch_name,
      $course_id,
      $delivery_mode,
      $medium_of_instruction,
      $is_enforced,
      $registration_open_date,
      $registration_close_date,
      $batch_start_date,
      $batch_end_date,
      $total_seat_count,
      $description,
      $status,
      $id
    );
    $st->execute();
    $st->close();

    if (is_bundle_course($conn, $course_id)) {
      // Keep batch modules synced if admins change the course to a bundle
      sync_bundle_modules_into_batch($conn, $id, $course_id);
      if ($is_enforced === 1) {
        propagate_bundle_enrollments($conn, $course_id, $id);
      }
    }

    echo "OK"; exit;
  }
}

if ($action === 'delete') {
  $id = (int)($_POST['id'] ?? 0);
  $st=$conn->prepare("DELETE FROM batches WHERE id=?");
  $st->bind_param('i',$id); $st->execute(); $st->close();
  echo "OK"; exit;
}
?>

<!-- (all your page styles remain exactly the same) -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.13.6/css/dataTables.bootstrap5.min.css" rel="stylesheet">
<style>
  body{background:#f5f7fb}
  .container{max-width:1600px}
  .card{box-shadow:0 4px 12px rgba(0,0,0,.07); border-radius:12px}
  .table td,.table th{vertical-align:middle}
  .modal-xl{max-width:1100px}
  .tl{position:relative;border:1px solid #e5e7eb;border-radius:.5rem;background:#fff;padding:16px 18px;margin-bottom:12px}
  .tl-line{position:absolute;left:40px;right:40px;top:44px;height:6px;background:#e9ecef;border-radius:6px}
  .tl-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}
  .mil{position:relative;text-align:center}
  .mil .dot{width:28px;height:28px;border-radius:999px;background:#adb5bd;margin:0 auto 8px;border:3px solid #fff;box-shadow:0 0 0 3px rgba(0,0,0,.04)}
  .mil.done .dot{background:#198754}
  .mil.current .dot{background:#0d6efd}
  .mil .lbl{font-size:.82rem;color:#6b7280}
  .mil .date{font-weight:700}
  .mil .pill{display:inline-block;margin-top:6px;padding:2px 8px;background:#e9ecef;border-radius:6px;font-size:.78rem}
</style>
<style>
  .ec-main { font-size:12.25px; }
  .ec-main .container-fluid{padding-top:.7rem!important;padding-bottom:.7rem!important;}
  .ec-main h1,.ec-main h2,.ec-main h3,.ec-main h4{margin-bottom:.4rem;}
  .ec-main h2.fw-bold{font-size:1.4rem;}
  .ec-main .btn{padding:.22rem .5rem;font-size:.78rem;border-radius:.3rem;}
  .ec-main .btn-sm{padding:.18rem .4rem;font-size:.74rem;}
  .ec-main .table{font-size:.85rem;}
  .ec-main .table th,.ec-main .table td{padding:.3rem .45rem;}
  .ec-main .table thead th{padding:.36rem .45rem;}
  .ec-main .badge,.ec-main .pill{font-size:.68rem;padding:.2rem .38rem;border-radius:.3rem;}
  .ec-main .dataTables_wrapper .dataTables_filter label{font-size:.82rem;margin-bottom:0;}
  .ec-main .dataTables_wrapper .dataTables_filter input{
    height:1.7rem;padding:.18rem .45rem;font-size:.82rem;border-radius:.3rem;
  }
  .ec-main .dataTables_wrapper .dataTables_length select{
    height:1.7rem;padding:.12rem .4rem;font-size:.82rem;border-radius:.3rem;
  }
  .ec-main .dataTables_wrapper .dataTables_info{font-size:.8rem;}
  .ec-main .dataTables_wrapper .dataTables_paginate .paginate_button{
    padding:.14rem .4rem!important;margin:0 .08rem!important;font-size:.8rem!important;
  }
  .ec-main .card{border-radius:8px;box-shadow:0 3px 9px rgba(0,0,0,.06);}
  .ec-main .form-control,.ec-main .form-select{padding:.32rem .5rem;font-size:.85rem;height:2rem;}
  .ec-main .modal-body{padding:1rem!important;}
  .ec-main .modal .form-label{font-size:.82rem;}
  .ec-main .tl{padding:10px 12px;}
  .ec-main .tl-line{left:28px;right:28px;top:30px;height:4px;}
  .ec-main .tl-grid{gap:10px;}
  .ec-main .mil .dot{width:18px;height:18px;margin:0 auto 4px;border-width:2px;}
  .ec-main .mil .lbl{font-size:.7rem;}
  .ec-main .mil .date{font-size:.82rem;}
  .ec-main .mil .pill{font-size:.66rem;padding:0 5px;}
</style>
<style>
  .rms-content { font-size: 12.5px; }
  .rms-content h1{ font-size:1.5rem; margin-bottom:.35rem; }
  .rms-content .btn{ padding:.22rem .50rem; font-size:.78rem; border-radius:.30rem; }
  .rms-content .btn-primary{ padding:.26rem .56rem; }
  .rms-content .table{ font-size:.84rem; }
  .rms-content .table th,
  .rms-content .table td{ padding:.30rem .45rem; }
  .rms-content .table thead th{ padding:.36rem .45rem; }
  .rms-content .badge,
  .rms-content .pill{ font-size:.68rem; padding:.22rem .40rem; border-radius:.30rem; }
  .rms-content .dataTables_wrapper .dataTables_filter label{ font-size:.82rem; }
  .rms-content .dataTables_wrapper .dataTables_filter input{
    height:1.7rem; padding:.18rem .45rem; font-size:.82rem; border-radius:.3rem;
  }
  .rms-content .dataTables_wrapper .dataTables_length select{
    height:1.7rem; padding:.12rem .40rem; font-size:.82rem; border-radius:.3rem;
  }
  .rms-content .dataTables_wrapper .dataTables_info{ font-size:.80rem; }
  .rms-content .dataTables_wrapper .dataTables_paginate .paginate_button{
    padding:.14rem .40rem !important; margin:0 .08rem !important; font-size:.80rem !important;
  }
  .rms-content .card{ border-radius:8px; }
  .rms-content .container, .rms-content .container-fluid{ padding-left:.5rem; padding-right:.5rem; }
  .rms-content .tl{ padding:10px 12px; }
  .rms-content .tl-line{ left:28px; right:28px; top:30px; height:4px; }
  .rms-content .tl-grid{ gap:10px; }
  .rms-content .mil .dot{ width:18px; height:18px; margin:0 auto 4px; border-width:2px; }
  .rms-content .mil .lbl{ font-size:.70rem; }
  .rms-content .mil .date{ font-size:.82rem; }
  .rms-content .mil .pill{ font-size:.68rem; padding:0 5px; }
</style>

<style>
  #manageModal .modal-content,
  #batchModal  .modal-content { font-size:12.25px; }
  #manageModal .modal-header, #manageModal .modal-body, #manageModal .modal-footer,
  #batchModal  .modal-header, #batchModal  .modal-body, #batchModal  .modal-footer { padding:.75rem 1rem; }
  #manageModal .modal-title, #batchModal .modal-title { font-size:1rem; }
  #manageModal .nav-link { padding:.25rem .6rem; font-size:.82rem; }
  #manageModal .btn, #batchModal .btn { padding:.22rem .5rem; font-size:.78rem; border-radius:.3rem; }
  #manageModal .btn-sm, #batchModal .btn-sm { padding:.18rem .4rem; font-size:.74rem; }
  #manageModal .table, #batchModal .table { font-size:.84rem; }
  #manageModal .table th, #manageModal .table td,
  #batchModal  .table th, #batchModal  .table td { padding:.30rem .45rem; }
  #manageModal .dataTables_wrapper .dataTables_filter label { font-size:.82rem; margin-bottom:0; }
  #manageModal .dataTables_wrapper .dataTables_filter input,
  #manageModal .dataTables_wrapper .dataTables_length select {
    height:1.6rem; padding:.18rem .45rem; font-size:.82rem; border-radius:.30rem;
  }
  #manageModal .dataTables_wrapper .dataTables_info { font-size:.80rem; }
  #manageModal .dataTables_wrapper .dataTables_paginate .paginate_button {
    padding:.14rem .40rem !important; margin:0 .08rem !important; font-size:.80rem !important;
  }
  #manageModal .tl{ padding:8px 10px; }
  #manageModal .tl-line{ left:24px; right:24px; top:28px; height:4px; }
  #manageModal .tl-grid{ gap:10px; }
  #manageModal .mil .dot{ width:16px; height:16px; margin:0 auto 4px; border-width:2px; }
  #manageModal .mil .lbl{ font-size:.70rem; }
  #manageModal .mil .date{ font-size:.80rem; }
  #manageModal .mil .pill{ font-size:.66rem; padding:0 5px; }
  #manageModal .modal-dialog,
#batchModal .modal-dialog{
  max-width: 1100px;
  margin: 1.75rem auto;
}

#manageModal .modal-content,
#batchModal .modal-content{
  border-radius: 16px;
  overflow: hidden;
}

#manageModal,
#batchModal{
  z-index: 1080;
}

.modal-backdrop{
  z-index: 1070;
}
  }
  
/* ===== BATCH PAGE HERO HEADER ===== */
.batch-shell{
  padding: 0 4px;
}

.batch-hero{
  background: #ffffff;
  border: 1px solid #e7ebf3;
  border-radius: 22px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05);
  padding: 20px 22px;
  margin-bottom: 16px;
}

.batch-hero-title{
  margin: 0;
  font-size: 2rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: #16233c;
}

.batch-hero-subtitle{
  margin: 6px 0 0;
  font-size: .95rem;
  color: #6f7b91;
}

.batch-hero-actions{
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  padding: .55rem .72rem !important;
  align-items: center;
}

.batch-top-card{
  background: #fff;
  border: 1px solid #e7ebf3;
  border-radius: 20px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05);
  padding: 14px;
}

.batch-top-card .dataTables_wrapper .dataTables_filter{
  margin-bottom: 10px;
}

.batch-top-card .dataTables_wrapper .dataTables_filter input{
  border-radius: 12px;
  border: 1px solid #d7dfeb;
  min-height: 38px;
}

.batch-top-card .table{
  margin-bottom: 0;
}

.batch-top-card .table thead th{
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: #74819a;
  border-top: 0;
}

.batch-top-card .table tbody tr:hover{
  background: #f9fbff;
}

.batch-status-badge{
  display: inline-flex;
  align-items: center;
  padding: 5px 10px;
  border-radius: 999px;
  font-size: .74rem;
  font-weight: 700;
}

.batch-status-active{
  background: #dff7e7;
  color: #199756;
}

.batch-status-inactive{
  background: #eceff3;
  color: #697586;
}

.batch-manage-btn{
  border-radius: 10px !important;
  padding: .32rem .62rem !important;
  font-weight: 600;
}

@media (max-width: 991.98px){
  .batch-hero{
    padding: 16px;
  }

  .batch-hero-title{
    font-size: 1.55rem;
  }

  .batch-hero-actions{
    width: 100%;
  }

  .batch-hero-actions .btn{
    flex: 1 1 auto;
  }
}
/* ===== ADD NEW BATCH BUTTON FIX ===== */
.batch-hero-actions .btn-primary{
  padding: 10px 18px !important;
  font-size: 0.95rem !important;
  font-weight: 700;
  border-radius: 12px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.batch-hero-actions .btn-primary i{
  font-size: 0.9rem;
}
</style>
<?php
/* --------------------- Normal page render --------------------- */
$ACTIVE = 'batches'; // highlight the current menu
include __DIR__ . '/../includes/header.php';
include __DIR__ . '/../includes/sidebar.php';
?>
<main class="ec-main"><!-- OPEN main right after sidebar -->
<div class="container-fluid py-4 batch-shell">

  <div class="batch-hero">
    <div class="d-flex justify-content-between align-items-center gap-3 flex-wrap">
      <div>
        <h1 class="batch-hero-title">Batch Management</h1>
        <p class="batch-hero-subtitle">
          Search, review, and manage course batches, schedules, seats, and enrollments.
        </p>
      </div>

      <div class="batch-hero-actions">
        
        <button id="btnAddBatch" type="button" class="btn btn-primary px-3">
          <i class="bi bi-plus-circle me-1"></i> Add New Batch
        </button>
      </div>
    </div>
  </div>

  <div class="batch-top-card">
    <div id="batchTable">
      <div class="p-4 text-center text-muted">Loading…</div>
    </div>
  </div>

</div>

<!-- Manage Modal -->
<div class="modal fade" id="manageModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-xl">
    <div class="modal-content rounded-4">
      <div class="modal-header">
        <h5 class="modal-title"><span id="mmTitle">View Batch</span> <small class="text-muted ms-2" id="mmId"></small></h5>
        <button class="btn-close" data-bs-dismiss="modal"></button>
      </div>
      <div class="modal-body">
        <ul class="nav nav-tabs mb-3">
          <li class="nav-item"><button id="tabBtnOverview" class="nav-link active" data-bs-toggle="tab" data-bs-target="#tabOverview">Overview</button></li>
          <li class="nav-item"><button id="tabBtnStudents" class="nav-link" data-bs-toggle="tab" data-bs-target="#tabStudents">Students</button></li>
        </ul>

        <div class="tab-content">
          <div class="tab-pane fade show active" id="tabOverview">
            <div id="tlWrap" class="mb-3"></div>
            <div id="ovrWrap" class="row g-3"></div>
            <div class="mt-3 d-flex gap-2">
              <button id="btnEditBatch" class="btn btn-outline-primary" type="button">Edit Batch</button>
              <button id="btnDeleteBatch" class="btn btn-outline-danger" type="button">Delete Batch</button>
            </div>
          </div>

          <div class="tab-pane fade" id="tabStudents">
            <div class="table-responsive">
              <table id="studentsTable" class="table table-striped w-100">
                <thead class="table-light">
                  <tr>
                    <th>Payment</th>
                    <th>Registration ID</th>
                    <th>Student ID</th>
                    <th>Available Seat</th>
                    <th>Name</th>
                    <th>Mobile</th>
                    <th>Email</th>
                    <th>Registered at</th>
                  </tr>
                </thead>
                <tbody></tbody>
              </table>
            </div>
          </div>
        </div>

      </div>
      <div class="modal-footer">
        <button class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>

<!-- Add/Edit Modal -->
<div class="modal fade" id="batchModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <form id="batchForm" class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="batchFormTitle">Add New Batch</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>
      <div class="modal-body">
        <input type="hidden" id="batch_id" name="batch_id">
        <div class="mb-3">
          <label class="form-label">Batch Name</label>
          <input type="text" class="form-control" id="batch_name" name="batch_name" required>
        </div>
        <div class="mb-3">
          <label class="form-label">Course</label>
          <select class="form-select" id="course_id" name="course_id" required>
            <option value="">Select Course</option>
            <?php
              $crs = $conn->query("SELECT id, course_name FROM courses ORDER BY course_name");
              while($c=$crs->fetch_assoc()) echo "<option value='{$c['id']}'>".h($c['course_name'])."</option>";
            ?>
          </select>
        </div>
        <div class="row g-3">
          <div class="col-md-6">
            <label class="form-label">Delivery Mode</label>
            <select class="form-select" id="delivery_mode" name="delivery_mode" required>
              <option value="">Select Mode</option>
              <option value="Weekday">Weekday</option>
              <option value="Weekend">Weekend</option>
            </select>
          </div>
          <div class="col-md-6">
            <label class="form-label">Medium of Instruction</label>
            <select class="form-select" id="medium_of_instruction" name="medium_of_instruction" required>
              <option value="">Select Medium</option>
              <option value="English">English</option>
              <option value="Sinhala">Sinhala</option>
              <option value="Tamil">Tamil</option>
            </select>
          </div>
        </div>
        <div class="row g-3 mt-1">
          <div class="col-md-6">
            <label class="form-label">Registration Open</label>
            <input type="date" class="form-control" id="registration_open_date" name="registration_open_date" required>
          </div>
          <div class="col-md-6">
            <label class="form-label">Registration Close</label>
            <input type="date" class="form-control" id="registration_close_date" name="registration_close_date" required>
          </div>
          <div class="col-md-6">
            <label class="form-label">Batch Start</label>
            <input type="date" class="form-control" id="batch_start_date" name="batch_start_date" required>
          </div>
          <div class="col-md-6">
            <label class="form-label">Batch End</label>
            <input type="date" class="form-control" id="batch_end_date" name="batch_end_date" required>
          </div>
        </div>
        <div class="row g-3 mt-1">
          <div class="col-md-6">
            <label class="form-label">Total Seat Count</label>
            <input type="number" min="0" class="form-control" id="total_seat_count" name="total_seat_count" value="30" required>
          </div>
          <div class="col-md-6">
            <label class="form-label">Enforced</label>
            <select class="form-select" id="is_enforced" name="is_enforced">
              <option value="0">No</option>
              <option value="1">Yes</option>
            </select>
          </div>
        </div>
        <div class="mt-3">
          <label class="form-label">Description</label>
          <textarea class="form-control" id="description" name="description" rows="2"></textarea>
        </div>
        <div class="mt-3">
          <label class="form-label">Status</label>
          <select class="form-select" id="status" name="status">
            <option>Active</option>
            <option>Inactive</option>
          </select>
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-success" type="submit">Save</button>
        <button class="btn btn-secondary" type="button" data-bs-dismiss="modal">Cancel</button>
      </div>
    </form>
  </div>
</div>

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

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.js"></script>
<script>
let currentBatchId = null;

function loadBatches(){
  $.post('batches.php', {action:'fetch'}).done(function(html){
    $('#batchTable').html(html);
    $('#batchesTable').DataTable({lengthChange:false, pageLength:10, dom:'frtip'});
  }).fail(function(xhr){ $('#batchTable').html('<div class="p-4 text-danger">Failed to load: '+(xhr.responseText||xhr.statusText)+'</div>');});
}
loadBatches();

/* -------- Manage modal -------- */
function openManage(id){
  currentBatchId = id;
  $.getJSON('batches.php', {action:'view', id:id}).done(function(d){
    $('#mmTitle').text(d.batch_name||'View Batch');
    $('#mmId').text('#'+d.id);

    $('#tlWrap').html(buildTimeline(
      d.registration_open_date, d.batch_start_date,
      d.registration_close_date, d.batch_end_date
    ));

    const o = `
      <div class="col-12 col-md-6">
        <div class="border rounded-3 p-3">
          <div class="fw-semibold mb-2">Batch Info</div>
          <div class="small text-muted">Course</div><div class="mb-2">${esc(d.course_name||'-')}</div>
          <div class="small text-muted">Delivery Mode</div><div class="mb-2">${esc(d.delivery_mode||'-')}</div>
          <div class="small text-muted">Medium</div><div class="mb-2">${esc(d.medium_of_instruction||'-')}</div>
          <div class="small text-muted">Description</div><div>${esc(d.description||'N/A')}</div>
        </div>
      </div>
      <div class="col-12 col-md-6">
        <div class="border rounded-3 p-3">
          <div class="fw-semibold mb-2">Seats</div>
          <div>Total: <b>${num(d.seats?.total)}</b></div>
          <div>Filled: <b>${num(d.seats?.filled)}</b></div>
          <div>Available: <b>${num(d.seats?.available)}</b></div>
        </div>
      </div>`;
    $('#ovrWrap').html(o);

    $('#btnEditBatch').off('click').on('click', function(){ openEditModal(id); });
    $('#btnDeleteBatch').off('click').on('click', function(){ deleteBatch(id); });

    const m = new bootstrap.Modal(document.getElementById('manageModal'));
    m.show();

    document.getElementById('tabBtnStudents').addEventListener('shown.bs.tab', function(){
      loadStudents(currentBatchId);
    }, {once:true});
  }).fail(function(xhr){ alert('Load failed: '+(xhr.responseText||xhr.statusText)); });
}

function loadStudents(batchId){
  $.getJSON('batches.php', {action:'students', id:batchId}).done(function(d){
    const tb = $('#studentsTable tbody').empty();
    (d.rows||[]).forEach(r=>{
      tb.append(`<tr>
        <td>${esc(r.payment||'-')}</td>
        <td>${esc(r.registration_id||'')}</td>
        <td>${esc(r.student_id||'')}</td>
        <td>${esc(String(d.available))}</td>
        <td>${esc(r.name||'')}</td>
        <td>${esc(r.mobile||'')}</td>
        <td>${esc(r.email||'')}</td>
        <td>${esc(r.registered_at||'')}</td>
      </tr>`);
    });
    if ($.fn.DataTable.isDataTable('#studentsTable')) $('#studentsTable').DataTable().destroy();
    $('#studentsTable').DataTable({lengthChange:false, pageLength:10, dom:'frtip', order:[[7,'desc']]});
  }).fail(function(xhr){ alert('Load students failed:\n\n'+(xhr.responseText||xhr.statusText)); });
}

/* -------- Add/Edit modal -------- */
document.getElementById('btnAddBatch')?.addEventListener('click', function(e){
  e.preventDefault();
  const form = document.getElementById('batchForm');
  form.reset();
  document.getElementById('batch_id').value = '';
  document.getElementById('batchFormTitle').textContent = 'Add New Batch';
  document.getElementById('status').value = 'Active';
  bootstrap.Modal.getOrCreateInstance(document.getElementById('batchModal')).show();
});

function openEditModal(id){
  $.get('batches.php', {action:'get', id:id}).done(function(raw){
    let b = {};
    try { b = JSON.parse(raw||'{}'); } catch(e){ console.error('Bad JSON', raw); b={}; }
    $('#batchFormTitle').text('Edit Batch');
    $('#batch_id').val(b.id||'');
    $('#batch_name').val(b.batch_name||'');
    $('#course_id').val(b.course_id||'');
    $('#delivery_mode').val(b.delivery_mode||'');
    $('#medium_of_instruction').val(b.medium_of_instruction||'');
    $('#registration_open_date').val(b.registration_open_date||'');
    $('#registration_close_date').val(b.registration_close_date||'');
    $('#batch_start_date').val(b.batch_start_date||'');
    $('#batch_end_date').val(b.batch_end_date||'');
    $('#total_seat_count').val(b.total_seat_count||0);
    $('#is_enforced').val(b.is_enforced||0);
    $('#description').val(b.description||'');
    $('#status').val(b.status||'Inactive');
    bootstrap.Modal.getOrCreateInstance(document.getElementById('batchModal')).show();
  }).fail(function(xhr){ alert('Open edit failed:\n\n'+(xhr.responseText||xhr.statusText)); });
}

$('#batchForm').on('submit', function(e){
  e.preventDefault();
  const isUpdate = !!$('#batch_id').val();
  const form = $(this).serialize() + '&action=' + (isUpdate ? 'update' : 'add');
  $.post('batches.php', form).done(function(txt){
    if (String(txt).trim() !== 'OK') { alert('Unexpected response: ' + txt); return; }
    bootstrap.Modal.getInstance(document.getElementById('batchModal')).hide();
    loadBatches();
  }).fail(function(xhr){ alert('Save failed:\n\n'+(xhr.responseText||xhr.statusText)); });
});

function deleteBatch(id){
  if (!confirm('Delete this batch?')) return;
  $.post('batches.php', {action:'delete', id:id}).done(function(){
    bootstrap.Modal.getInstance(document.getElementById('manageModal')).hide();
    loadBatches();
  }).fail(function(xhr){ alert('Delete failed:\n\n'+(xhr.responseText||xhr.statusText)); });
}

/* utils */
function fmt(s){ return s ? new Date(s).toISOString().slice(0,10) : 'N/A'; }
function num(v){ return (v==null)?'0':String(v); }
function esc(str){ const d=document.createElement('div'); d.textContent=(str==null?'':str); return d.innerHTML; }

/* build timeline */
function buildTimeline(open, start, close, end){
  const items = [
    {lbl:'Registration Opened', date:open},
    {lbl:'Batch Starting', date:start},
    {lbl:'Registration Closing', date:close},
    {lbl:'Batch Ending', date:end}
  ];
  const now = new Date();
  const html = items.map((it,i)=>{
    const dt = it.date ? new Date(it.date) : null;
    let cls=''; if (dt){ if (dt < now) cls='done'; else cls='upcoming'; }
    if (!dt || dt>=now){
      const idx = items.findIndex(x=>x.date && new Date(x.date)>=now);
      if (idx===i) cls='current';
    }
    return `
      <div class="mil ${cls}">
        <div class="dot"></div>
        <div class="lbl">${esc(it.lbl)}</div>
        <div class="date">${esc(fmt(it.date))}</div>
        <div class="pill">${esc(relText(it.date))}</div>
      </div>`;
  }).join('');
  return `<div class="tl"><div class="tl-line"></div><div class="tl-grid">${html}</div></div>`;
}
function relText(s){
  if (!s) return 'N/A';
  const a=new Date(), b=new Date(s);
  const ms=b-a, d=Math.round(ms/86400000);
  if (d===0) return 'today';
  if (d>0){
    if (d===1) return '1 day from now';
    if (d>=30) return Math.round(d/30)+' month'+(Math.round(d/30)>1?'s':'')+' from now';
    return d+' days from now';
  }else{
    if (d===-1) return '1 day ago';
    if (d<=-30) return Math.round(Math.abs(d)/30)+' month'+(Math.round(Math.abs(d)/30)>1?'s':'')+' ago';
    return Math.abs(d)+' days ago';
  }
}
</script>

<?php // close main opened above ?>
</main>
