<?php
// Student › Modules — Full-Bleed Reader + Slide-in Drawer (STACKED layout)
// File: /elms/student/modules.php
declare(strict_types=1);
if (session_status() === PHP_SESSION_NONE) session_start();

/* ---------- bootstrap ---------- */
require_once __DIR__.'/../includes/app.php';
require_once __DIR__.'/../includes/db.php';
$auth = __DIR__.'/../includes/student_auth.php';
if (is_file($auth)) require_once $auth;
if (!function_exists('require_student')) {
  function require_student(): void {
    $next = $_SERVER['REQUEST_URI'] ?? '/';
    header('Location: '.app_url('/student/login.php?next='.rawurlencode($next)));
    exit;
  }
}
require_student();

/* ---------- helpers ---------- */
if (!function_exists('esc')) {
  function esc($s){ return htmlspecialchars((string)$s, ENT_QUOTES|ENT_SUBSTITUTE, 'UTF-8'); }
}
function t_exists(string $t): bool { global $mysqli;
  $st=$mysqli->prepare("SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=? LIMIT 1");
  $st->bind_param('s',$t); $st->execute(); $st->store_result(); $ok=$st->num_rows>0; $st->close(); return $ok;
}
function c_exists(string $t,string $c): bool { global $mysqli;
  $st=$mysqli->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->close(); return $ok;
}
function abs_url_from_value(string $v): string {
  $v=trim(str_replace('\\','/',$v)); if ($v==='') return '';
  if (preg_match('~^(?:[a-z]+:)?//~i',$v) || (isset($v[0]) && $v[0]==='d' && str_starts_with($v,'data:'))) return $v;
  $base=rtrim(app_url('/'),'/'); return ($v && $v[0]==='/') ? $base.$v : $base.'/'.$v;
}
function detect_file_url_from_row(array $row): string {
  foreach(['file_url','url','path','file','content_url','link','filepath','file_path','filename','attachment','document','resource','location','source'] as $k){
    if (!empty($row[$k])) return abs_url_from_value((string)$row[$k]);
  }
  foreach($row as $v){
    if (!is_string($v)) continue; $vv=trim($v);
    if ($vv==='') continue;
    if (preg_match('~^https?://|/uploads/~i',$vv)) return abs_url_from_value($vv);
  }
  return '';
}
function detect_kind(string $t, string $url): string {
  $t=strtolower($t); $ext=strtolower(pathinfo((string)(parse_url($url,PHP_URL_PATH)??''), PATHINFO_EXTENSION));
  if (str_contains($t,'quiz'))  return 'quiz';
  if (str_contains($t,'pdf')||$ext==='pdf') return 'pdf';
  if (str_contains($t,'video')||in_array($ext,['mp4','webm','ogg','mov','mkv'],true)) return 'video';
  if (str_contains($t,'audio')||in_array($ext,['mp3','wav','m4a','aac','oga'],true)) return 'audio';
  if (str_contains($t,'image')||in_array($ext,['jpg','jpeg','png','gif','webp','svg'],true)) return 'image';
  return 'link';
}
function kind_icon(string $k): string {
  return ['pdf'=>'📄','video'=>'🎥','audio'=>'🎧','image'=>'🖼️','quiz'=>'📝'][$k] ?? '🔗';
}

/* ---------- student → real courses (Bundle aware) ---------- */
$student_id = (int)($_SESSION['student_id'] ?? 0);
$courses = [];

if ($student_id > 0 && t_exists('enrollments') && t_exists('batches') && t_exists('courses')) {
  // Prefer real courses from bundle mapping via batch_modules.source_course_id
  if (t_exists('batch_modules') && c_exists('batch_modules','source_course_id')) {
    $sql = "
      SELECT DISTINCT sc.id, COALESCE(sc.course_name, CONCAT('Course ', sc.id)) AS course_name
      FROM enrollments e
      JOIN batches b         ON b.id = e.batch_id
      JOIN batch_modules bm  ON bm.batch_id = b.id
      JOIN courses sc        ON sc.id = bm.source_course_id
      WHERE e.student_id = ?
      ORDER BY sc.course_name
    ";
    $st = $mysqli->prepare($sql);
    $st->bind_param('i', $student_id);
    $st->execute();
    if ($res = $st->get_result()) { $courses = $res->fetch_all(MYSQLI_ASSOC); $res->close(); }
    $st->close();
  }
  // Fallback to batch's own course if no mapping rows
  if (!$courses) {
    $sql = "
      SELECT DISTINCT c.id, COALESCE(c.course_name, CONCAT('Course ', c.id)) AS course_name
      FROM enrollments e
      JOIN batches b ON b.id = e.batch_id
      JOIN courses c ON c.id = b.course_id
      WHERE e.student_id = ?
      ORDER BY c.course_name
    ";
    $st = $mysqli->prepare($sql);
    $st->bind_param('i', $student_id);
    $st->execute();
    if ($res = $st->get_result()) { $courses = $res->fetch_all(MYSQLI_ASSOC); $res->close(); }
    $st->close();
  }
}

/* ---------- choose course ---------- */
$course_id = (int)($_GET['course_id'] ?? 0);
if (!$course_id && $courses) $course_id = (int)$courses[0]['id'];

$course_name='Course';
if ($course_id && t_exists('courses')) {
  $st=$mysqli->prepare("SELECT COALESCE(course_name, CONCAT('Course ',id)) FROM courses WHERE id=? LIMIT 1");
  $st->bind_param('i',$course_id); $st->execute();
  if ($res = $st->get_result()) { if ($row=$res->fetch_row()) $course_name=(string)$row[0]; $res->close(); }
  $st->close();
}

/* ---------- modules & items for selected course ---------- */
$MOD_TBL = t_exists('lms_modules') ? 'lms_modules' : (t_exists('course_modules') ? 'course_modules' : null);
if (!$MOD_TBL) { $PAGE_TITLE='Modules — '.$course_name; $ACTIVE_MENU='modules';
  $top = __DIR__.'/studentlayout_top.php'; $topAlt = __DIR__.'/layout_top.php'; require is_file($top)?$top:$topAlt;
  echo '<div class="p-4 text-danger">No modules table found.</div>';
  $bot = __DIR__.'/studentlayout_bottom.php'; $botAlt = __DIR__.'/layout_bottom.php'; require is_file($bot)?$bot:$botAlt; exit;
}
$TITLE_COL = c_exists($MOD_TBL,'title') ? 'title' : (c_exists($MOD_TBL,'name') ? 'name' : 'id');
$ORDER_COL = c_exists($MOD_TBL,'sort_order') ? 'sort_order' : 'id';

$by_sem=[]; $allmods=[];
if ($course_id > 0) {
  $st=$mysqli->prepare("
    SELECT m.id, m.`$TITLE_COL` AS title,
           COALESCE(ms.semester_no,1) AS sem,
           COALESCE(ms.position, m.`$ORDER_COL`, m.id) AS pos
    FROM `$MOD_TBL` m
    LEFT JOIN elms_module_semesters ms ON ms.module_id=m.id
    WHERE m.course_id=?
    ORDER BY sem, pos, m.id
  ");
  $st->bind_param('i',$course_id); $st->execute(); $rs=$st->get_result();
  while($row=$rs->fetch_assoc()){ $row['id']=(int)$row['id']; $row['items']=[]; $by_sem[(int)$row['sem']][]=$row; $allmods[]=$row; }
  $rs->close(); $st->close();
}

/* ---------- content items ---------- */
$CONTENT_TBL = null;
foreach(['lms_content','lms_contents','lms_module_contents','module_contents','lms_content_items'] as $t){ if(t_exists($t)){ $CONTENT_TBL=$t; break; } }
$C_MID = $CONTENT_TBL ? (c_exists($CONTENT_TBL,'module_id') ? 'module_id' : (c_exists($CONTENT_TBL,'lms_module_id') ? 'lms_module_id' : null)) : null;

if ($CONTENT_TBL && $C_MID && $allmods){
  $ids=implode(',', array_map('intval', array_column($allmods,'id')));
  $res=$mysqli->query("SELECT t.*, t.`$C_MID` AS mid FROM `$CONTENT_TBL` t WHERE t.`$C_MID` IN ($ids) ORDER BY t.`$C_MID`, t.id");
  $byMid=[]; if ($res){ while($r=$res->fetch_assoc()) $byMid[(int)$r['mid']][]=$r; $res->close(); }
  foreach($by_sem as $semNo=>&$mods){
    foreach($mods as &$m){
      $rows=$byMid[$m['id']] ?? [];
      foreach($rows as $row){
        $iid=(int)($row['id'] ?? $row['content_id'] ?? 0);
        $title=(string)($row['title'] ?? $row['name'] ?? $row['topic'] ?? ('Item #'.$iid));
        $ctype=(string)($row['type'] ?? $row['mime_type'] ?? $row['content_type'] ?? $row['file_type'] ?? '');
        $quiz=(int)($row['quiz_id'] ?? $row['exam_id'] ?? 0);
        $url=abs_url_from_value(detect_file_url_from_row($row));
        $kind=$quiz>0 ? 'quiz' : detect_kind($ctype,$url);
        $m['items'][]=['id'=>$iid,'title'=>$title,'ctype'=>$kind,'url'=>$url,'quiz_id'=>$quiz];
      }
    } unset($m);
  } unset($mods);
}

/* ---------- render ---------- */
$MODULE_URL = rtrim(dirname($_SERVER['REQUEST_URI'] ?? '/student/modules.php'), '/').'/module_content.php';
$PAGE_TITLE = 'Modules — '.$course_name;
$ACTIVE_MENU = 'modules';
$top = __DIR__.'/studentlayout_top.php'; $topAlt = __DIR__.'/layout_top.php'; require is_file($top)?$top:$topAlt;
?>
<style>
/* Full width + reader + STACKED drawer styles */
:root{--ink:#0f172a;--muted:#64748b;--line:#e6eaf3;--accent:#0B3C89;--accent2:#2563eb;--shadow:0 12px 28px rgba(2,8,23,.06)}
.fullbleed-root{font-family:Inter,ui-sans-serif,system-ui;color:var(--ink)}
.reader-bar{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:12px;padding:8px 10px;background:#fff;box-shadow:var(--shadow);margin:8px 0}
.btn{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);background:#fff;border-radius:10px;padding:8px 12px;text-decoration:none;color:var(--ink)}
.course-rail{display:flex;gap:8px;overflow:auto;padding:4px;border:1px solid var(--line);border-radius:999px;background:#fff}
.course-rail a{padding:8px 12px;border:1px solid var(--line);border-radius:999px;text-decoration:none;color:var(--ink);white-space:nowrap}
.course-rail a.active{background:linear-gradient(90deg,var(--accent),var(--accent2));color:#fff;border-color:transparent;box-shadow:0 10px 20px rgba(37,99,235,.22)}
.canvas{margin-top:10px;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:#fff;min-height:calc(100vh - 160px)}
#contentPane iframe, #contentPane embed, #contentPane object{width:100%!important;height:calc(100vh - 190px)!important;border:0!important;display:block!important}
/* Drawer */
.drawer-backdrop{position:fixed;inset:0;background:rgba(2,6,23,.45);opacity:0;pointer-events:none;transition:opacity .2s;z-index:1100}
.drawer{position:fixed;top:0;left:0;height:100vh;width:380px;max-width:94vw;background:#fff;border-right:1px solid var(--line);
  box-shadow:0 16px 40px rgba(0,0,0,.24);transform:translateX(-100%);transition:transform .24s;z-index:1110;display:flex;flex-direction:column}
.fullbleed-root[data-drawer="open"] .drawer{transform:translateX(0)}
.fullbleed-root[data-drawer="open"] .drawer-backdrop{opacity:1;pointer-events:auto}
.drawer-head{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid var(--line)}
.drawer-body{padding:10px 12px 16px;overflow:auto}
/* STACKED: module header then items below */
.sem{border:1px solid var(--line);border-radius:12px;overflow:hidden;margin-bottom:10px}
.sem-head{width:100%;display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border:0;background:#f8fbff;font-weight:800;cursor:pointer}
.sem-body{padding:6px 10px 12px}
.mod{border:1px solid var(--line);border-radius:12px;padding:10px;margin:10px 0;background:#fff}
.mod-title{font-weight:800;line-height:1.25}
.mod-sub{font-size:12px;color:var(--muted);margin-top:2px}
.items{margin-top:8px}
.item-row{display:flex;align-items:center;justify-content:space-between;gap:10px;border:1px dashed var(--line);border-radius:10px;padding:10px;margin:6px 0;background:#fff}
.item-left{display:flex;align-items:center;gap:10px;min-width:0}
.item-ico{font-size:17px;flex:0 0 auto}
.item-text{min-width:0}
.item-title{font-weight:700;line-height:1.25;word-break:break-word}
.item-sub{font-size:12.5px;color:var(--muted)}
.item-row.active{border-color:#0B3C89;box-shadow:0 0 0 3px rgba(11,60,137,.12)}
@media (max-width: 720px){.drawer{width:92vw}}
</style>

<div class="fullbleed-root" id="fbRoot" data-drawer="open">
  <div class="reader-bar">
    <div style="display:flex;gap:8px">
      <button class="btn" id="openDrawerBtn" type="button">☰ Modules</button>
      <button class="btn" id="prevBtn" type="button">← Prev</button>
      <button class="btn" id="nextBtn" type="button">Next →</button>
    </div>
    <div class="btn" style="flex:1;justify-content:flex-start;font-weight:800" id="contentTitle">Content</div>
    <div style="display:flex;gap:8px">
      <a id="openExternal" class="btn" href="#" target="_blank" rel="noopener">View externally ↗</a>
      <button id="fullscreenBtn" class="btn" type="button" title="Fullscreen">Fullscreen ⤢</button>
    </div>
  </div>

  <nav class="course-rail" aria-label="Choose course">
    <?php foreach($courses as $c):
      $cid=(int)$c['id']; $active=($cid===$course_id); ?>
      <a href="?course_id=<?= $cid ?>" class="<?= $active?'active':'' ?>" <?= $active?'aria-current="page"':'' ?>>
        <?= esc($c['course_name']) ?>
      </a>
    <?php endforeach; ?>
  </nav>

  <div id="contentPane" class="canvas" aria-live="polite">
    <div style="padding:16px;color:#64748b;text-align:center">Open the Modules drawer and select an item to start learning.</div>
  </div>

  <div class="drawer-backdrop" id="drawerBackdrop" aria-hidden="true"></div>
  <aside class="drawer" id="drawer" role="dialog" aria-modal="true" aria-label="Modules & units">
    <div class="drawer-head">
      <div style="font-weight:800">My Courses · Modules</div>
      <button type="button" class="btn" id="closeDrawerBtn">✕</button>
    </div>
    <div class="drawer-body">

      <?php if ($course_id<=0): ?>
        <div class="mod">No course found for this student.</div>
      <?php else: ?>
        <?php ksort($by_sem); $__i=0; foreach($by_sem as $semNo=>$mods): $open=($__i++===0); ?>
          <section class="sem">
            <button type="button" class="sem-head" data-acc="<?= $open?'open':'closed' ?>">
              <span>Semester <?= (int)$semNo ?></span>
              <span class="mod-sub"><?= count($mods) ?> module<?= count($mods)==1?'':'s' ?></span>
            </button>
            <div class="sem-body" style="<?= $open?'':'display:none' ?>">
              <?php foreach($mods as $m): ?>
                <div class="mod">
                  <div class="mod-title"><?= esc($m['title']) ?></div>
                  <div class="mod-sub"><?= count($m['items']) ?> item<?= count($m['items'])==1?'':'s' ?></div>

                  <div class="items">
                    <?php if (!$m['items']): ?>
                      <div class="item-row"><div class="item-left"><span class="item-ico">ℹ️</span><div class="item-text"><div class="item-title">No items</div></div></div></div>
                    <?php else: $__n=0; foreach($m['items'] as $it):
                      $iid=(int)$it['id']; $kind=$it['ctype']; $url=$it['url']; $ico=kind_icon($kind);
                      $viewHere = $MODULE_URL.'?item_id='.$iid; $num = ++$__n; ?>
                      <div class="item-row" data-item-id="<?= $iid ?>" data-url="<?= esc($url) ?>" data-kind="<?= esc($kind) ?>" data-title="<?= esc($it['title']) ?>" tabindex="0">
                        <div class="item-left">
                          <span class="item-ico"><?= $ico ?></span>
                          <div class="item-text">
                            <div class="item-title"><?= $num ?>. <?= esc($it['title']) ?></div>
                            <div class="item-sub"><?= esc($kind) ?></div>
                          </div>
                        </div>
                        <div><a class="btn open-inline" href="<?= esc($viewHere) ?>">View</a></div>
                      </div>
                    <?php endforeach; endif; ?>
                  </div>
                </div>
              <?php endforeach; ?>
            </div>
          </section>
        <?php endforeach; ?>
      <?php endif; ?>

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

<script>
/* Drawer open/close */
(()=>{const root=document.getElementById('fbRoot'),o=document.getElementById('openDrawerBtn'),c=document.getElementById('closeDrawerBtn'),b=document.getElementById('drawerBackdrop');
  function open(){root.setAttribute('data-drawer','open')} function close(){root.setAttribute('data-drawer','closed')}
  o.addEventListener('click',open); c.addEventListener('click',close); b.addEventListener('click',close); document.addEventListener('keydown',e=>{if(e.key==='Escape') close()})
})();
/* Accordion */
document.querySelectorAll('.sem-head').forEach(h=>h.addEventListener('click',()=>{const o=h.getAttribute('data-acc')==='open';h.setAttribute('data-acc',o?'closed':'open');const body=h.nextElementSibling;if(body) body.style.display=o?'none':'';}));
/* Inline viewer + prev/next + external + fullscreen */
(()=>{const pane=document.getElementById('contentPane'),title=document.getElementById('contentTitle'),openEx=document.getElementById('openExternal'),prev=document.getElementById('prevBtn'),next=document.getElementById('nextBtn'),root=document.getElementById('fbRoot'),fsBtn=document.getElementById('fullscreenBtn');const items=Array.from(document.querySelectorAll('.item-row .open-inline')).map(a=>a.closest('.item-row')).filter(Boolean);
  function idxActive(){return items.findIndex(el=>el.classList.contains('active'))}
  function setActive(i){items.forEach(el=>el.classList.remove('active')); if(i>=0&&i<items.length){const el=items[i];el.classList.add('active'); title.textContent=el.dataset.title||'Content'; openEx.href=el.dataset.url||'#';} else {title.textContent='Content'; openEx.href='#';} prev.disabled=(i<=0); next.disabled=(i<0||i>=items.length-1)}
  async function load(href){pane.innerHTML='<div style="padding:16px;color:#64748b;text-align:center">Loading…</div>'; try{const r=await fetch(href,{credentials:'same-origin'}); pane.innerHTML=r.ok?await r.text():'<div class="p-3 text-danger">Couldn’t load content (HTTP '+r.status+').</div>'; const h=pane.querySelector('[data-content-title]'); if(h) title.textContent=h.getAttribute('data-content-title')||title.textContent; root.setAttribute('data-drawer','closed'); pane.scrollIntoView({behavior:'smooth',block:'start'});}catch(_){pane.innerHTML='<div style="padding:16px;color:#b91c1c">Network error.</div>'}}
  document.addEventListener('click',e=>{const a=e.target.closest('a.open-inline'); if(!a) return; e.preventDefault(); const i=items.indexOf(a.closest('.item-row')); setActive(i); load(a.href);});
  document.addEventListener('keydown',e=>{if(e.key!=='Enter') return; const row=e.target.closest('.item-row'); if(!row) return; const link=row.querySelector('a.open-inline'); if(link) link.click();});
  prev.addEventListener('click',()=>{const i=idxActive(); if(i<=0) return; items[i-1].querySelector('a.open-inline').click();});
  next.addEventListener('click',()=>{const i=idxActive(); if(i<0||i>=items.length-1) return; items[i+1].querySelector('a.open-inline').click();});
  fsBtn.addEventListener('click',()=>{const el=document.getElementById('contentPane'); if(!document.fullscreenElement){el.requestFullscreen?.();} else {document.exitFullscreen?.();}});
  setActive(-1);
})();
</script>

<?php
$bot = __DIR__.'/studentlayout_bottom.php';
$botAlt = __DIR__.'/layout_bottom.php';
require is_file($bot) ? $bot : $botAlt;
