<?php
// /edenrms/pages/approvals.php — RMS-style unified list
declare(strict_types=1);
@header('Content-Type: text/html; charset=utf-8');

$DEBUG = (isset($_GET['debug']) && $_GET['debug'] === '1');
if ($DEBUG) {
  ini_set('display_errors', '1');
  ini_set('display_startup_errors', '1');
  error_reporting(E_ALL);
} else {
  error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE);
}

if (session_status() !== PHP_SESSION_ACTIVE) session_start();

/* ---------- Auth + DB ---------- */
$ROOT  = dirname(__DIR__);
$AUTH  = $ROOT . '/includes/auth.php';
$DBINC = $ROOT . '/includes/db.php';

$db = null;
try {
  if (is_file($AUTH)) {
    require_once $AUTH;
    if (function_exists('require_role')) require_role(['super_admin','branch_admin','accountant','coordinator']);
    if (function_exists('ec_db')) $db = ec_db();
  }

  if (!$db && is_file($DBINC)) {
    require_once $DBINC;
    if (isset($conn) && $conn instanceof mysqli) $db = $conn;
  }

  if (!$db) $db = @new mysqli('localhost', 'root', '', 'edencamp_edencampus');
  if ($db instanceof mysqli) @$db->set_charset('utf8mb4');
} catch (Throwable $e) {
  http_response_code(500);
  echo $DEBUG ? "<pre>DB bootstrap error:\n" . $e->getMessage() . "</pre>" : "Error initializing database.";
  exit;
}

/* ---------- CSRF ---------- */
if (empty($_SESSION['csrf_token'])) $_SESSION['csrf_token'] = bin2hex(random_bytes(16));
$CSRF = $_SESSION['csrf_token'];

/* ---------- Helpers ---------- */
function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8'); }
function nf($n){ return number_format((float)$n, 2); }

function t_exists(mysqli $db, string $t): bool {
  try {
    $st = $db->prepare("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=?");
    $st->bind_param('s', $t);
    $st->execute();
    $st->store_result();
    $ok = $st->num_rows > 0;
    $st->free_result();
    $st->close();
    return $ok;
  } catch (Throwable $e) {
    return false;
  }
}

function c_exists(mysqli $db, string $t, string $c): bool {
  try {
    $st = $db->prepare("SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? AND COLUMN_NAME=?");
    $st->bind_param('ss', $t, $c);
    $st->execute();
    $st->store_result();
    $ok = $st->num_rows > 0;
    $st->free_result();
    $st->close();
    return $ok;
  } catch (Throwable $e) {
    return false;
  }
}

/* fetch-all without get_result() */
function stmt_all_assoc(mysqli_stmt $st): array {
  $meta = $st->result_metadata();
  if (!$meta) return [];
  $fields = [];
  $row = [];
  $bind = [];
  while ($f = $meta->fetch_field()) {
    $fields[] = $f->name;
    $row[$f->name] = null;
    $bind[] = &$row[$f->name];
  }
  $meta->free();
  call_user_func_array([$st, 'bind_result'], $bind);

  $out = [];
  while ($st->fetch()) {
    $r = [];
    foreach ($fields as $f) $r[$f] = $row[$f];
    $out[] = $r;
  }
  return $out;
}

/* ---------- Filters ---------- */
$tab = strtolower($_GET['tab'] ?? 'pending');
$validTabs = ['pending','approved','rejected','all'];
if (!in_array($tab, $validTabs, true)) $tab = 'pending';

$whereStatus = ($tab === 'all') ? '1' : 'ar.status=?';
$statusParam = ($tab === 'all') ? null : $tab;

/* ---------- Data query ---------- */
$haveAR      = t_exists($db, 'approval_requests');
$haveStu     = t_exists($db, 'studentss');
$haveCourses = t_exists($db, 'courses');
$haveUsers   = t_exists($db, 'users') || t_exists($db, 'elms_users');

$rows = [];

if ($haveAR) {
  $joinStu    = $haveStu ? "LEFT JOIN studentss s ON s.id = COALESCE(ar.student_id, ar.ref_id)" : "";
  $joinCourse = ($haveCourses && c_exists($db, 'approval_requests', 'course_id'))
    ? "LEFT JOIN courses c ON c.id = ar.course_id"
    : "";

  $reqJoin = "";
  $reqSel  = "NULL AS requester";

  if ($haveUsers && c_exists($db, 'approval_requests', 'requested_by')) {
    if (t_exists($db, 'users') && c_exists($db, 'users', 'full_name')) {
      $reqJoin = "LEFT JOIN users u ON u.id = ar.requested_by";
      $reqSel  = "COALESCE(u.full_name,u.username) AS requester";
    } elseif (t_exists($db, 'elms_users') && c_exists($db, 'elms_users', 'full_name')) {
      $reqJoin = "LEFT JOIN elms_users u ON u.id = ar.requested_by";
      $reqSel  = "COALESCE(u.full_name,u.username) AS requester";
    }
  } elseif (c_exists($db, 'approval_requests', 'requested_by_name')) {
    $reqSel = "ar.requested_by_name AS requester";
  }

  $sql = "
    SELECT
      ar.id,
      ar.type,
      ar.status,
      ar.payload,
      ar.requested_at,
      COALESCE(ar.student_id, ar.ref_id) AS sid,
      " . ($haveStu ? "s.full_name" : "NULL") . " AS student_name,
      " . ($haveStu && c_exists($db, 'studentss', 'center_reg_no') ? "s.center_reg_no" : "NULL") . " AS center_reg_no,
      " . ($haveStu && c_exists($db, 'studentss', 'reference_no') ? "s.reference_no" : "NULL") . " AS reference_no,
      " . ($haveCourses ? "c.course_name" : "NULL") . " AS course_name,
      $reqSel
    FROM approval_requests ar
    $joinStu
    $joinCourse
    $reqJoin
    WHERE $whereStatus
    ORDER BY ar.requested_at DESC, ar.id DESC
  ";

  try {
    $st = $db->prepare($sql);
    if ($statusParam !== null) $st->bind_param('s', $statusParam);
    $st->execute();
    $rows = stmt_all_assoc($st);
    $st->close();
  } catch (Throwable $e) {
    if ($DEBUG) echo "<pre>Query error: " . $e->getMessage() . "</pre>";
    $rows = [];
  }
}

/* ---------- Counters ---------- */
function count_status(mysqli $db, string $s): int {
  if (!t_exists($db, 'approval_requests')) return 0;
  try {
    $st = $db->prepare("SELECT COUNT(*) FROM approval_requests WHERE status=?");
    $st->bind_param('s', $s);
    $st->execute();
    $st->bind_result($c);
    $st->fetch();
    $st->close();
    return (int)$c;
  } catch (Throwable $e) {
    return 0;
  }
}

$cntP = count_status($db, 'pending');
$cntA = count_status($db, 'approved');
$cntR = count_status($db, 'rejected');

/* ---------- Status helpers ---------- */
function pill($text, $tone) {
  $cls = [
    'red'   => 'pill pill-red',
    'green' => 'pill pill-green',
    'gray'  => 'pill pill-gray',
    'blue'  => 'pill pill-blue',
  ][$tone] ?? 'pill pill-gray';

  return '<span class="' . $cls . '">' . h($text) . '</span>';
}

function badgeRequested($status) {
  $m = strtolower((string)$status);
  if ($m === 'approved') return pill('Completed', 'green');
  if ($m === 'rejected') return pill('Rejected', 'gray');
  return pill('Active', 'red');
}

function badgeRegistration(array $r): string {
  return pill('Expired', 'red');
}

function badgePayment(mysqli $db, array $r): string {
  if (!t_exists($db, 'payments')) return pill('N/A', 'gray');
  try {
    $st = $db->prepare("SELECT COALESCE(SUM(amount),0) FROM payments WHERE student_id=?");
    $sid = (int)($r['sid'] ?? 0);
    $st->bind_param('i', $sid);
    $st->execute();
    $st->bind_result($sum);
    $st->fetch();
    $st->close();
    return ((float)$sum > 0) ? pill('Completed', 'green') : pill('Pending', 'red');
  } catch (Throwable $e) {
    return pill('N/A', 'gray');
  }
}

function badgeUniFee(array $payload): string {
  if (isset($payload['university_fee_usd'])) {
    return ((float)$payload['university_fee_usd'] > 0) ? pill('Pending', 'gray') : pill('N/A', 'gray');
  }
  return pill('N/A', 'gray');
}

function regRef(array $r): string {
  $ref = $r['center_reg_no'] ?? '';
  if (!$ref) $ref = $r['reference_no'] ?? '';
  return $ref ? h($ref) : '—';
}

function isActive($cur, $tab) {
  return $cur === $tab ? 'active' : '';
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>RMS :: Approvals</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">

<style>
:root{
  --rms-blue:#243b8f;
  --rms-muted:#6b7280;
  --table-border:#e5e7eb;
  --row-hover:#f8fbff;
  --card-shadow:0 10px 30px rgba(15,23,42,.06);
  --soft-bg:#f4f7fb;
}

body{
  background:
    radial-gradient(circle at top right, rgba(36,59,143,.06), transparent 20%),
    linear-gradient(180deg, #f8fbff 0%, #f2f5fa 100%);
}

.page-wrap{
  max-width:1650px;
  margin:18px auto;
}

.page-title{
  font-weight:800;
  color:#0f172a;
  font-size:1.1rem;
  margin-bottom:.65rem;
  letter-spacing:.2px;
}

.nav-rms{
  gap:.45rem;
}

.nav-rms .nav-link{
  border-radius:999px;
  padding:.38rem .8rem;
  font-size:.84rem;
  font-weight:600;
  color:#334155;
  background:#fff;
  border:1px solid #e2e8f0;
  transition:.2s ease;
}

.nav-rms .nav-link:hover{
  background:#eff6ff;
  color:#1d4ed8;
  border-color:#bfdbfe;
}

.nav-rms .nav-link.active{
  background:linear-gradient(135deg, #243b8f, #1d4ed8);
  color:#fff;
  border-color:transparent;
  box-shadow:0 8px 20px rgba(37,99,235,.22);
}

.card-rms{
  background:#fff;
  border:1px solid #e8edf4;
  border-radius:18px;
  box-shadow:var(--card-shadow);
  overflow:hidden;
}

.tbl{
  margin:0;
  font-size:.92rem;
}

.tbl th,
.tbl td{
  vertical-align:middle;
  padding:.78rem .8rem;
}

.tbl thead th{
  padding:.82rem .8rem;
  border-bottom:1px solid var(--table-border);
}

.tbl tbody tr{
  transition:.18s ease;
}

.tbl tbody tr:hover{
  background:var(--row-hover);
}

.th-muted{
  color:#334155;
  font-weight:700;
  background:linear-gradient(180deg,#f8fafc,#f1f5f9);
  border-bottom:1px solid var(--table-border);
}

.sub{
  font-size:.76rem;
  color:#64748b;
}

.pill{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  min-width:84px;
  font-size:.69rem;
  line-height:1;
  padding:.38rem .55rem;
  border-radius:999px;
  font-weight:800;
  letter-spacing:.2px;
  box-shadow:inset 0 -1px 0 rgba(255,255,255,.18);
}

.pill-red{color:#fff;background:linear-gradient(135deg,#ef4444,#dc2626)}
.pill-green{color:#fff;background:linear-gradient(135deg,#10b981,#059669)}
.pill-gray{color:#fff;background:linear-gradient(135deg,#64748b,#475569)}
.pill-blue{color:#fff;background:linear-gradient(135deg,#3b82f6,#2563eb)}

.act-link{
  color:#1e3a8a;
  text-decoration:none;
  font-size:.9rem;
  font-weight:600;
}

.act-link:hover{
  color:#1d4ed8;
  text-decoration:underline;
}

.col-compact{
  white-space:nowrap;
}

.table-responsive{
  border-radius:18px;
}

#approvalsTableWrap .table > :not(caption) > * > *{
  border-color:#eef2f7;
}

.modal-content{
  border:none;
  border-radius:18px;
  box-shadow:0 18px 50px rgba(15,23,42,.18);
}

.modal-header{
  background:linear-gradient(180deg,#f8fafc,#f1f5f9);
  border-bottom:1px solid #e5e7eb;
}

.modal-footer{
  border-top:1px solid #e5e7eb;
}

.btn-primary{
  background:linear-gradient(135deg,#243b8f,#2563eb);
  border:none;
  box-shadow:0 8px 20px rgba(37,99,235,.2);
}

.btn-primary:hover{
  filter:brightness(1.03);
}
</style>
</head>
<body>

<?php
$ACTIVE = 'student';
include __DIR__ . '/../includes/header.php';
include __DIR__ . '/../includes/sidebar.php';
?>

<main class="ec-main">
  <div class="page-wrap container-fluid">

    <div class="d-flex justify-content-between align-items-center">
      <div class="page-title">REGISTRATION STATUS CHANGE REQUESTS</div>
      <ul class="nav nav-pills nav-rms">
        <li class="nav-item">
          <a class="nav-link <?= isActive('pending', $tab) ?>" href="?tab=pending">
            Pending <span class="badge bg-secondary ms-1"><?= (int)$cntP ?></span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link <?= isActive('approved', $tab) ?>" href="?tab=approved">
            Approved <span class="badge bg-secondary ms-1"><?= (int)$cntA ?></span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link <?= isActive('rejected', $tab) ?>" href="?tab=rejected">
            Rejected <span class="badge bg-secondary ms-1"><?= (int)$cntR ?></span>
          </a>
        </li>
        <li class="nav-item">
          <a class="nav-link <?= isActive('all', $tab) ?>" href="?tab=all">All</a>
        </li>
      </ul>
    </div>

    <div id="approvalsTableWrap" class="card-rms mt-2">
      <div class="table-responsive">
        <table class="table table-bordered tbl">
          <thead class="th-muted">
            <tr>
              <th style="width:280px">Student</th>
              <th class="text-center" style="width:420px">Status</th>
              <th>Reason / Course</th>
              <th class="text-center" style="width:110px">Branch</th>
              <th class="text-center" style="width:140px">Date Requested</th>
              <th class="text-center" style="width:120px">Requester</th>
              <th class="text-center" style="width:120px">Action</th>
            </tr>
            <tr>
              <th></th>
              <th class="text-center sub">Requested &nbsp;|&nbsp; Registration &nbsp;|&nbsp; Payment &nbsp;|&nbsp; University Fee</th>
              <th></th><th></th><th></th><th></th><th></th>
            </tr>
          </thead>
          <tbody>
          <?php if (!empty($rows)): ?>
            <?php foreach ($rows as $r):
              $p       = json_decode((string)($r['payload'] ?? ''), true) ?: [];
              $student = trim((string)($r['student_name'] ?? '')) ?: '-';
              $ref     = regRef($r);
              $course  = trim((string)($r['course_name'] ?? ''));
              $reason  = trim((string)($p['reason'] ?? ''));
              $reqAt   = trim((string)($r['requested_at'] ?? ''));
              $reqBy   = trim((string)($r['requester'] ?? '')) ?: '—';
              $sid     = (int)($r['sid'] ?? 0);

              $badgeReq = badgeRequested($r['status'] ?? '');
              $badgeReg = badgeRegistration($r);
              $badgePay = badgePayment($db, $r);
              $badgeUni = badgeUniFee($p);
            ?>
            <tr data-appr-id="<?= (int)$r['id'] ?>">
              <td>
                <?php if ($sid > 0): ?>
                  <div>
                    <a class="act-link js-open-student"
                       href="/edenrms/pages/student_action_tabs.php?id=<?= $sid ?>"
                       data-id="<?= $sid ?>"><?= h($student) ?></a>
                  </div>
                <?php else: ?>
                  <div><?= h($student) ?></div>
                <?php endif; ?>
                <div class="sub"><?= h($ref) ?></div>
              </td>
              <td class="text-center col-compact">
                <?= $badgeReq ?> &nbsp; <?= $badgeReg ?> &nbsp; <?= $badgePay ?> &nbsp; <?= $badgeUni ?>
              </td>
              <td>
                <div><?= $reason ? h($reason) : '—' ?></div>
                <?php if ($course): ?>
                  <div class="sub"><?= h($course) ?></div>
                <?php endif; ?>
              </td>
              <td class="text-center">—</td>
              <td class="text-center sub"><?= h($reqAt) ?></td>
              <td class="text-center"><?= h($reqBy) ?></td>
              <td class="text-center">
                <a class="act-link me-3" href="/edenrms/pages/approval_view.php?id=<?= (int)$r['id'] ?>">View</a>
                <a class="act-link btn-review"
                   href="javascript:void(0)"
                   data-id="<?= (int)$r['id'] ?>"
                   data-summary="<?= h(ucwords(str_replace('_', ' ', $r['type'] ?? 'request'))) ?>">Review</a>
              </td>
            </tr>
            <?php endforeach; ?>
          <?php else: ?>
            <tr>
              <td colspan="7" class="text-center py-4 text-muted">
                <i class="bi bi-inboxes me-1"></i>No requests.
              </td>
            </tr>
          <?php endif; ?>
          </tbody>
        </table>
      </div>
    </div>

  </div>

  <!-- Decision Modal -->
  <div class="modal fade" id="decideModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog">
      <form class="modal-content" id="decideForm">
        <div class="modal-header">
          <h5 class="modal-title">
            <i class="bi bi-shield-check me-2"></i><span id="decideTitle">Approve</span> Request
          </h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
        </div>
        <div class="modal-body">
          <input type="hidden" name="id" id="decideId" value="">
          <input type="hidden" name="decision" id="decideValue" value="approve">
          <input type="hidden" name="csrf" value="<?= h($CSRF) ?>">
          <div class="mb-2 text-muted">
            <i class="bi bi-info-circle me-1"></i><span id="decideSummary">—</span>
          </div>
          <label class="form-label">Note <span class="text-muted">(optional for approve, required for reject)</span></label>
          <textarea class="form-control" rows="3" name="note" id="decideNote" placeholder="Enter a note…"></textarea>
        </div>
        <div class="modal-footer">
          <button class="btn btn-secondary" data-bs-dismiss="modal" type="button">Cancel</button>
          <button class="btn btn-primary" id="decideSubmit" type="submit">
            <i class="bi bi-send me-1"></i><span id="decideBtnLabel">Approve</span>
          </button>
        </div>
      </form>
    </div>
  </div>

  <!-- Student Overview Modal -->
  <div class="modal fade" id="actionModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog modal-xl modal-dialog-scrollable">
      <div class="modal-content">
        <div class="modal-header py-2">
          <h5 class="modal-title"><i class="bi bi-ui-checks-grid me-2"></i>Student Overview</h5>
          <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
        </div>
        <div class="modal-body text-center py-5">
          <div class="spinner-border text-info"></div>
        </div>
      </div>
    </div>
  </div>

  <!-- Approval View Modal -->
  <div class="modal fade" id="apprViewModal" tabindex="-1" aria-hidden="true">
    <div class="modal-dialog modal-xl modal-dialog-scrollable">
      <div class="modal-content">
        <div class="modal-header py-2">
          <h5 class="modal-title"><i class="bi bi-file-earmark-text me-2"></i>Request Details</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
        </div>
        <div class="modal-body p-0">
          <div class="p-3 text-muted">Loading…</div>
        </div>
      </div>
    </div>
  </div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
async function parseJSONSafe(res){
  const text = await res.text();
  try {
    return { json: JSON.parse(text), text };
  } catch {
    const clean = text.replace(/^\uFEFF/, '').trim();
    const s = clean.indexOf('{');
    const e = clean.lastIndexOf('}');
    if (s !== -1 && e !== -1 && e > s) {
      try {
        return { json: JSON.parse(clean.slice(s, e + 1)), text };
      } catch {}
    }
    return { json: null, text };
  }
}

let decideMode = 'approve';
const decideModal   = document.getElementById('decideModal');
const decideForm    = document.getElementById('decideForm');
const decideTitle   = document.getElementById('decideTitle');
const decideBtnLbl  = document.getElementById('decideBtnLabel');
const decideId      = document.getElementById('decideId');
const decideVal     = document.getElementById('decideValue');
const decideNote    = document.getElementById('decideNote');
const decideSummary = document.getElementById('decideSummary');

function openDecision(id, mode, summary){
  decideMode = (mode === 'reject') ? 'reject' : 'approve';
  decideId.value = id || '';
  decideVal.value = decideMode;
  decideTitle.textContent = (decideMode === 'approve') ? 'Approve' : 'Reject';
  decideBtnLbl.textContent = (decideMode === 'approve') ? 'Approve' : 'Reject';
  decideSummary.textContent = summary || '';
  decideNote.value = '';
  decideNote.required = (decideMode === 'reject');
  bootstrap.Modal.getOrCreateInstance(decideModal).show();
}

decideForm.addEventListener('submit', async (e) => {
  e.preventDefault();

  const submitBtn = document.getElementById('decideSubmit');
  submitBtn.disabled = true;
  submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Saving...';

  try {
    const fd = new FormData(decideForm);

    const decision = (fd.get('decision') || decideMode || 'approve').toString().toLowerCase();
    fd.set('decision', decision);
    fd.set('action', decision);
    fd.set('do', decision);

    const id = (fd.get('id') || '').toString();
    if (!fd.get('request_id')) fd.set('request_id', id);

    const res = await fetch('/edenrms/ajax/approval_decide.php', {
      method: 'POST',
      body: fd,
      credentials: 'include'
    });

    const { json, text } = await parseJSONSafe(res);
    if (!json) throw new Error('Server did not return JSON.\n' + text.slice(0, 200));
    if (json.ok === false) throw new Error(json.error || json.message || 'Request failed');

    const row = document.querySelector(`tr[data-appr-id="${id}"]`);
    if (row) {
      const statusCell = row.children[1];
      if (statusCell) {
        const pills = statusCell.querySelectorAll('.pill');
        if (pills[0]) {
          pills[0].outerHTML = (json.status === 'approved')
            ? '<span class="pill pill-green">Completed</span>'
            : '<span class="pill pill-gray">Rejected</span>';
        }
      }
    }

    const apprViewModalEl = document.getElementById('apprViewModal');
    const statusCell = apprViewModalEl?.querySelector('#statusCell');
    if (statusCell && json.status) {
      statusCell.textContent = json.status;
    }

    bootstrap.Modal.getInstance(decideModal)?.hide();
    bootstrap.Modal.getInstance(apprViewModalEl)?.hide();
  } catch (err) {
    alert('Error: ' + (err.message || 'Unknown error'));
  } finally {
    submitBtn.disabled = false;
    submitBtn.innerHTML = '<i class="bi bi-send me-1"></i>' + (decideMode === 'approve' ? 'Approve' : 'Reject');
  }
});

function openActionTabs(id, href){
  const el = document.getElementById('actionModal');
  const body = el.querySelector('.modal-body');
  const modal = bootstrap.Modal.getOrCreateInstance(el, { backdrop:'static', keyboard:false });

  body.innerHTML = '<div class="text-center py-5"><div class="spinner-border text-info"></div></div>';
  modal.show();

  fetch(href, { credentials: 'same-origin' })
    .then(r => r.text())
    .then(html => { body.innerHTML = html; })
    .catch(err => {
      body.innerHTML = '<div class="p-3 text-danger">Failed: ' + (err.message || 'Error') + '</div>';
    });
}

document.addEventListener('click', function(e){
  const a = e.target.closest('.js-open-student');
  if (!a) return;
  e.preventDefault();
  openActionTabs(a.getAttribute('data-id') || '', a.href);
});

const apprViewModal = document.getElementById('apprViewModal');
const apprViewBody  = apprViewModal?.querySelector('.modal-body');

document.addEventListener('click', function(e){
  const a = e.target.closest('a[href*="/edenrms/pages/approval_view.php"]');
  if (!a) return;

  e.preventDefault();
  apprViewBody.innerHTML = '<div class="p-3 text-muted">Loading…</div>';
  bootstrap.Modal.getOrCreateInstance(apprViewModal, { backdrop:'static', keyboard:false }).show();

  fetch(a.href, { credentials:'same-origin' })
    .then(r => r.text())
    .then(html => {
      apprViewBody.innerHTML = html;
      bindApproveRejectInView();
    })
    .catch(err => {
      apprViewBody.innerHTML = '<div class="p-3 text-danger">Failed: ' + (err.message || 'Error') + '</div>';
    });
});

function bindApproveRejectInView() {
  const modal = document.getElementById('apprViewModal');
  const body  = modal?.querySelector('.modal-body');
  if (!body) return;

  body.addEventListener('click', function(ev){
    const btn = ev.target.closest('.js-approve, .js-reject, [data-decision], #btnApprove, #btnReject');
    if (!btn) return;

    ev.preventDefault();

    let decision = 'approve';
    if (
      btn.classList.contains('js-reject') ||
      btn.id === 'btnReject' ||
      (btn.getAttribute('data-decision') || '') === 'reject'
    ) {
      decision = 'reject';
    }

    let apprId = btn.getAttribute('data-id');
    if (!apprId) {
      const host = body.querySelector('[data-appr-id]');
      if (host) apprId = host.getAttribute('data-appr-id');
    }
    if (!apprId) {
      const hdr = body.querySelector('h1,h2,h3,.fw-semibold');
      if (hdr) {
        const m = (hdr.textContent || '').match(/#(\d+)/);
        if (m) apprId = m[1];
      }
    }
    if (!apprId) {
      alert('Cannot determine approval id');
      return;
    }

    const summary = btn.getAttribute('data-summary') || 'Request';
    openDecision(apprId, decision, summary);
  }, { once: true });
}

document.addEventListener('click', function(e){
  const btn = e.target.closest('.btn-review');
  if (!btn) return;

  e.preventDefault();
  const id = btn.getAttribute('data-id') || '';
  const summary = btn.getAttribute('data-summary') || 'Request';
  openDecision(id, 'approve', summary);
});
</script>
</main>
</body>
</html>