<?php
declare(strict_types=1);
require_once __DIR__ . '/ajax/tp_auth.php';
$teacher_id = tp_require_auth_page();
$name       = htmlspecialchars($_SESSION['tp_user_name'] ?? 'Teacher');
$initials   = strtoupper(implode('', array_map(fn($w) => $w[0], array_slice(explode(' ', $name), 0, 2))));
$tab        = htmlspecialchars($_GET['tab'] ?? 'today');
$hasProgress = function_exists('hasModule') && hasModule('progress_analytics');
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#4f46e5">
<title>Teacher Portal</title>
<link rel="manifest" href="manifest.php">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<link rel="stylesheet" href="assets/tp.css">
<?php if ($hasProgress): ?>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script>
<style>
.prog-kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:12px}
.prog-kpi{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:10px 8px;text-align:center}
.prog-kpi .v{font-size:1.15rem;font-weight:700;color:#1e293b;line-height:1.1;font-variant-numeric:tabular-nums}
.prog-kpi .l{font-size:.62rem;text-transform:uppercase;letter-spacing:.03em;color:#94a3b8;margin-top:3px}
.prog-chart{position:relative;height:220px}
.prog-tbl{width:100%;border-collapse:collapse;font-size:.78rem}
.prog-tbl th{text-align:left;color:#64748b;font-weight:600;padding:6px 8px;border-bottom:2px solid #eef2f7;white-space:nowrap}
.prog-tbl td{padding:6px 8px;border-bottom:1px solid #f1f5f9;color:#1e293b;font-variant-numeric:tabular-nums}
.prog-grade{display:inline-block;min-width:22px;text-align:center;color:#fff;font-weight:700;border-radius:5px;padding:1px 6px}
@media(max-width:420px){.prog-kpis{grid-template-columns:repeat(2,1fr)}}
</style>
<?php endif; ?>
</head>
<body>

<div id="tp-offline-banner"><i class="fas fa-wifi-slash"></i> You are offline — some features unavailable</div>
<div id="tp-install-bar">
  <span><i class="fas fa-download"></i> Install Teacher Portal for quick access</span>
  <button id="tp-install-btn">Install</button>
  <button onclick="document.getElementById('tp-install-bar').remove()">✕</button>
</div>

<div id="tp-shell">

  <!-- Header -->
  <header id="tp-header">
    <h1><i class="fas fa-chalkboard-teacher" style="opacity:.7;margin-right:.4rem;"></i>Teacher Portal</h1>
    <div class="tp-header-actions">
      <div id="tp-notices-bell" style="position:relative;cursor:pointer;" onclick="openTab('notices')">
        <i class="fas fa-bell" style="color:rgba(255,255,255,.8);font-size:1.1rem;"></i>
        <span id="notice-bell-badge" class="tp-badge"></span>
      </div>
      <div class="tp-avatar" onclick="showUserMenu()" title="<?= $name ?>"><?= $initials ?></div>
    </div>
  </header>

  <!-- User menu dropdown -->
  <div id="user-menu" style="display:none;position:fixed;top:56px;right:.75rem;background:#fff;border-radius:10px;box-shadow:0 4px 20px rgba(0,0,0,.12);z-index:200;min-width:180px;overflow:hidden;">
    <div style="padding:.75rem 1rem;border-bottom:1px solid #e2e8f0;">
      <div style="font-weight:600;font-size:.9rem;"><?= $name ?></div>
      <div style="font-size:.75rem;color:#64748b;"><?= htmlspecialchars($_SESSION['tp_user_role'] ?? '') ?></div>
    </div>
    <a href="logout.php" style="display:flex;align-items:center;gap:.6rem;padding:.65rem 1rem;color:#dc2626;font-size:.88rem;text-decoration:none;">
      <i class="fas fa-sign-out-alt"></i> Sign Out
    </a>
  </div>

  <!-- Main content -->
  <main id="tp-main">

    <!-- ═══ TODAY ══════════════════════════════════════════════ -->
    <section class="tp-section active" id="sec-today">
      <div id="today-content"><div class="tp-loading"><div class="tp-spinner"></div></div></div>
    </section>

    <!-- ═══ TIMETABLE ══════════════════════════════════════════ -->
    <section class="tp-section" id="sec-timetable">
      <div id="timetable-content"><div class="tp-loading"><div class="tp-spinner"></div></div></div>
    </section>

    <!-- ═══ ATTENDANCE ═════════════════════════════════════════ -->
    <section class="tp-section" id="sec-attendance">
      <div class="tp-card">
        <div class="tp-controls">
          <select id="att-class" class="tp-select" onchange="loadAttendance()"></select>
          <input type="date" id="att-date" class="tp-input" value="<?= date('Y-m-d') ?>" onchange="loadAttendance()">
        </div>
        <button class="tp-btn tp-btn-outline tp-btn-sm" onclick="markAllPresent()" style="margin-bottom:.6rem;">
          <i class="fas fa-check-double"></i> Mark All Present
        </button>
        <div id="att-list"></div>
        <div id="att-saved-notice" style="display:none;font-size:.78rem;color:#16a34a;margin-bottom:.5rem;">
          <i class="fas fa-check-circle"></i> Attendance already saved for this date
        </div>
      </div>
      <button id="att-save-btn" class="tp-btn tp-btn-primary tp-btn-block" onclick="saveAttendance()" style="display:none;">
        <i class="fas fa-save"></i> Save Attendance
      </button>
    </section>

    <!-- ═══ MARKS ══════════════════════════════════════════════ -->
    <section class="tp-section" id="sec-marks">
      <div class="tp-card">
        <div class="tp-controls">
          <select id="marks-class" class="tp-select" onchange="loadSubjectsForMarks()"></select>
          <select id="marks-subject" class="tp-select" onchange="loadMarks()"></select>
        </div>
        <div id="marks-meta" style="font-size:.78rem;color:#64748b;margin-bottom:.5rem;"></div>
        <div id="marks-list"></div>
      </div>
      <button id="marks-save-btn" class="tp-btn tp-btn-primary tp-btn-block" onclick="saveMarks()" style="display:none;">
        <i class="fas fa-save"></i> Save All Marks
      </button>
    </section>

    <!-- ═══ ASSESSMENTS (SBA) ═══════════════════════════════════ -->
    <section class="tp-section" id="sec-assess">
      <div class="tp-card">
        <div class="tp-controls">
          <select id="assess-class" class="tp-select" onchange="loadSubjectsForAssess()"></select>
          <select id="assess-subject" class="tp-select" onchange="loadAssessBoard()"></select>
        </div>
        <div id="assess-meta" style="font-size:.78rem;color:#64748b;margin-bottom:.4rem;"></div>
      </div>

      <!-- Components manager (collapsible) -->
      <div class="tp-card">
        <div style="display:flex;align-items:center;justify-content:space-between;cursor:pointer;" onclick="toggleAssessComps()">
          <div class="tp-card-title" style="margin:0;"><i class="fas fa-sliders-h"></i> Assessment Components</div>
          <i class="fas fa-chevron-down" id="assess-comps-chevron"></i>
        </div>
        <div id="assess-comps-wrap" style="display:none;margin-top:.6rem;">
          <div style="font-size:.74rem;color:#94a3b8;margin-bottom:.5rem;">
            These roll up into the continuous-assessment score. Weights are relative.
          </div>
          <div id="assess-comps-list"></div>
          <button class="tp-btn tp-btn-outline tp-btn-sm" onclick="addComponentRow()" style="margin-top:.4rem;">
            <i class="fas fa-plus"></i> Add Component
          </button>
          <button class="tp-btn tp-btn-primary tp-btn-sm" onclick="saveComponents()" style="margin-top:.4rem;">
            <i class="fas fa-save"></i> Save Components
          </button>
        </div>
      </div>

      <!-- Score entry -->
      <div class="tp-card">
        <div class="tp-card-title" style="margin-bottom:.5rem;"><i class="fas fa-pen"></i> Enter Scores</div>
        <select id="assess-comp-pick" class="tp-select" onchange="renderAssessGrid()" style="margin-bottom:.5rem;"></select>
        <div id="assess-list"></div>
      </div>
      <button id="assess-save-btn" class="tp-btn tp-btn-primary tp-btn-block" onclick="saveAssessScores()" style="display:none;">
        <i class="fas fa-save"></i> Save Assessment Scores
      </button>
    </section>

    <!-- ═══ PROGRESS ANALYTICS ══════════════════════════════════ -->
    <section class="tp-section" id="sec-progress">
      <div class="tp-card">
        <div class="tp-controls">
          <select id="prog-level" class="tp-select" onchange="progOnLevel()">
            <option value="school">My classes</option>
            <option value="class">One class</option>
            <option value="student">One student</option>
          </select>
          <select id="prog-class" class="tp-select" onchange="progOnClass()" style="display:none;"></select>
        </div>
        <div class="tp-controls" style="margin-top:.4rem;">
          <select id="prog-student" class="tp-select" onchange="progLoad()" style="display:none;"></select>
          <select id="prog-term" class="tp-select" onchange="progLoad()"></select>
        </div>
        <div id="prog-meta" style="font-size:.78rem;color:#64748b;margin-top:.4rem;"></div>
      </div>

      <div id="prog-kpis" class="prog-kpis"></div>

      <div class="tp-card">
        <div class="tp-card-title" style="margin-bottom:.4rem;"><i class="fas fa-chart-line"></i> <span id="prog-trend-title">Performance trend</span></div>
        <div class="prog-chart"><canvas id="prog-trend"></canvas></div>
      </div>

      <div class="tp-card">
        <div class="tp-card-title" style="margin-bottom:.4rem;"><i class="fas fa-chart-simple"></i> Subject performance</div>
        <div class="prog-chart"><canvas id="prog-subjects"></canvas></div>
      </div>

      <div class="tp-card">
        <div class="tp-card-title" style="margin-bottom:.4rem;"><i class="fas fa-table"></i> <span id="prog-table-title">Breakdown</span></div>
        <div id="prog-table" style="overflow-x:auto;"></div>
      </div>
    </section>

    <!-- ═══ LESSON PLANS ════════════════════════════════════════ -->
    <section class="tp-section" id="sec-plans">
      <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:.6rem;">
        <select id="plans-class" class="tp-select" style="max-width:160px;" onchange="loadPlans()"></select>
        <button class="tp-btn tp-btn-primary tp-btn-sm" onclick="openPlanModal()">
          <i class="fas fa-plus"></i> New Plan
        </button>
      </div>
      <div class="tp-card">
        <div id="plans-list"></div>
      </div>
    </section>

    <!-- ═══ LESSON NOTES ════════════════════════════════════════ -->
    <section class="tp-section" id="sec-notes">
      <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:.6rem;">
        <select id="notes-class" class="tp-select" style="max-width:160px;" onchange="loadNotes()"></select>
        <button class="tp-btn tp-btn-primary tp-btn-sm" onclick="openNoteModal()">
          <i class="fas fa-plus"></i> New Note
        </button>
      </div>
      <div class="tp-card">
        <div id="notes-list"></div>
      </div>
    </section>

    <!-- ═══ HOMEWORK ════════════════════════════════════════════ -->
    <section class="tp-section" id="sec-homework">
      <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:.6rem;">
        <select id="hw-class" class="tp-select" style="max-width:160px;" onchange="loadHomework()"></select>
        <button class="tp-btn tp-btn-primary tp-btn-sm" onclick="openHwModal()">
          <i class="fas fa-plus"></i> Assign
        </button>
      </div>
      <div class="tp-card">
        <div id="hw-list"></div>
      </div>
    </section>

    <!-- ═══ MY CLASSES ═══════════════════════════════════════════ -->
    <section class="tp-section" id="sec-class">
      <div class="tp-controls" style="margin-bottom:.6rem;">
        <select id="class-sel" class="tp-select" onchange="onClassSelChange()"></select>
        <select id="class-subject-sel" class="tp-select" onchange="loadMyClass()">
          <option value="">All Subjects</option>
        </select>
      </div>
      <div id="class-content"></div>
    </section>

    <!-- ═══ NOTICES ════════════════════════════════════════════ -->
    <section class="tp-section" id="sec-notices">
      <div class="tp-card" id="notices-list"></div>
      <button id="notices-more-btn" class="tp-btn tp-btn-outline tp-btn-block" style="display:none;margin-top:.5rem;" onclick="loadMoreNotices()">
        Load more
      </button>
    </section>

    <!-- ═══ STUDENT SUPPORT ══════════════════════════════════════ -->
    <section class="tp-section" id="sec-support">
      <div class="tp-controls" style="margin-bottom:.6rem;">
        <select id="support-class" class="tp-select" onchange="loadSupport()"></select>
      </div>
      <div id="support-tier-tabs" style="display:flex;gap:.4rem;margin-bottom:.75rem;overflow-x:auto;padding-bottom:2px;">
        <button class="tp-tier-tab active" data-tier="all"     onclick="showIntTab('all')">All</button>
        <button class="tp-tier-tab"        data-tier="critical" onclick="showIntTab('critical')"><span class="int-dot critical"></span>Critical</button>
        <button class="tp-tier-tab"        data-tier="atrisk"   onclick="showIntTab('atrisk')"><span class="int-dot atrisk"></span>At Risk</button>
        <button class="tp-tier-tab"        data-tier="monitor"  onclick="showIntTab('monitor')"><span class="int-dot monitor"></span>Monitor</button>
      </div>
      <div id="support-list"></div>
    </section>

  </main><!-- /tp-main -->

  <!-- Bottom Nav -->
  <nav id="tp-nav">
    <button class="tp-nav-btn active" id="nav-today" onclick="openTab('today')">
      <i class="fas fa-home"></i><span>Today</span>
    </button>
    <button class="tp-nav-btn" id="nav-timetable" onclick="openTab('timetable')">
      <i class="fas fa-calendar-week"></i><span>Timetable</span>
    </button>
    <button class="tp-nav-btn" id="nav-attendance" onclick="openTab('attendance')">
      <i class="fas fa-user-check"></i><span>Attendance</span>
    </button>
    <button class="tp-nav-btn" id="nav-marks" onclick="openTab('marks')">
      <i class="fas fa-star"></i><span>Marks</span>
    </button>
    <button class="tp-nav-btn" id="nav-more" onclick="openMore()">
      <i class="fas fa-ellipsis-h"></i><span>More</span>
    </button>
  </nav>

</div><!-- /tp-shell -->

<!-- ── More Drawer ──────────────────────────────────────────── -->
<div id="tp-more-backdrop" onclick="closeMore()"></div>
<div id="tp-more-drawer">
  <div class="tp-drawer-grip"></div>
  <div class="tp-drawer-grid">
    <button class="tp-drawer-item" onclick="openTab('assess');closeMore()"><i class="fas fa-list-check"></i>Assessments</button>
    <?php if ($hasProgress): ?>
    <button class="tp-drawer-item" onclick="openTab('progress');closeMore()"><i class="fas fa-chart-line"></i>Progress</button>
    <?php endif; ?>
    <button class="tp-drawer-item" onclick="openTab('plans');closeMore()">
      <i class="fas fa-book-open"></i>Lesson Plans
    </button>
    <button class="tp-drawer-item" onclick="openTab('notes');closeMore()">
      <i class="fas fa-pencil-alt"></i>Lesson Notes
    </button>
    <button class="tp-drawer-item" onclick="openTab('homework');closeMore()">
      <i class="fas fa-tasks"></i>Homework
    </button>
    <button class="tp-drawer-item" onclick="openTab('class');closeMore()">
      <i class="fas fa-users"></i>My Classes
    </button>
    <button class="tp-drawer-item" onclick="openTab('notices');closeMore()">
      <i class="fas fa-bullhorn"></i>Notices
    </button>
    <button class="tp-drawer-item" onclick="openTab('support');closeMore()">
      <i class="fas fa-hands-helping"></i>Student Support
    </button>
  </div>
</div>

<!-- Intervention modal -->
<div class="tp-modal-backdrop" id="int-modal">
  <div class="tp-modal-sheet">
    <div class="tp-modal-header">
      <h2 id="int-modal-title">Log Intervention</h2>
      <button class="tp-modal-close" onclick="closeIntModal()">&times;</button>
    </div>
    <div id="int-student-name" style="font-size:.85rem;color:#64748b;margin-bottom:.75rem;"></div>
    <form id="int-form" onsubmit="saveIntervention(event)">
      <input type="hidden" id="int-student-id" value="0">
      <input type="hidden" id="int-class-name" value="">
      <div class="tp-row-2">
        <div class="tp-form-group">
          <label class="tp-label">Type</label>
          <select id="int-type" class="tp-select" required>
            <option value="academic">Academic</option>
            <option value="attendance">Attendance</option>
            <option value="behaviour">Behaviour</option>
            <option value="general">General</option>
          </select>
        </div>
        <div class="tp-form-group">
          <label class="tp-label">Follow-up Date</label>
          <input type="date" id="int-followup" class="tp-input">
        </div>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Note <span style="color:#dc2626">*</span></label>
        <textarea id="int-note" class="tp-textarea" rows="3" placeholder="Describe the concern or observation…" required></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Action Taken</label>
        <textarea id="int-action" class="tp-textarea" rows="2" placeholder="Steps taken or planned…"></textarea>
      </div>
      <div class="tp-form-group" style="display:flex;align-items:center;gap:.5rem;">
        <input type="checkbox" id="int-visible" style="width:16px;height:16px;" checked>
        <label for="int-visible" style="font-size:.85rem;margin:0;cursor:pointer;">
          Share with parent
        </label>
      </div>
      <div style="display:flex;gap:.6rem;margin-top:.75rem;">
        <button type="submit" class="tp-btn tp-btn-primary" style="flex:1;">
          <i class="fas fa-save"></i> Save
        </button>
        <button type="button" class="tp-btn tp-btn-outline" onclick="closeIntModal()" style="flex:1;">
          Cancel
        </button>
      </div>
    </form>
    <!-- History sub-panel -->
    <div id="int-history" style="margin-top:1rem;border-top:1px solid #e2e8f0;padding-top:.75rem;display:none;">
      <div style="font-size:.78rem;font-weight:700;color:#64748b;text-transform:uppercase;margin-bottom:.5rem;">
        Previous Notes
      </div>
      <div id="int-history-list"></div>
    </div>
  </div>
</div>

<!-- Toast -->
<div id="tp-toast" class="tp-toast"></div>

<!-- ══ MODALS ══════════════════════════════════════════════════ -->

<!-- Plan modal -->
<div class="tp-modal-backdrop" id="plan-modal">
  <div class="tp-modal-sheet">
    <div class="tp-modal-header">
      <h2 id="plan-modal-title">Lesson Plan</h2>
      <button class="tp-modal-close" onclick="closePlanModal()">&times;</button>
    </div>
    <form id="plan-form" onsubmit="savePlan(event)">
      <input type="hidden" id="plan-id" value="0">
      <div class="tp-row-2">
        <div class="tp-form-group">
          <label class="tp-label">Class</label>
          <select id="plan-class" class="tp-select" required onchange="loadSubjectsForForm('plan')"></select>
        </div>
        <div class="tp-form-group">
          <label class="tp-label">Week Starting</label>
          <input type="date" id="plan-week" class="tp-input" required>
        </div>
      </div>
      <div class="tp-row-2">
        <div class="tp-form-group">
          <label class="tp-label">Subject</label>
          <select id="plan-subject" class="tp-select"></select>
        </div>
        <div class="tp-form-group" style="align-self:end;">
        </div>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Objectives</label>
        <textarea id="plan-objectives" class="tp-textarea" placeholder="Learning objectives for the week…"></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Content</label>
        <textarea id="plan-content" class="tp-textarea" placeholder="Topics and content to be covered…"></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Teaching Methods</label>
        <textarea id="plan-methods" class="tp-textarea" style="min-height:60px;" placeholder="Methods and strategies…"></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Materials / Resources</label>
        <textarea id="plan-materials" class="tp-textarea" style="min-height:60px;" placeholder="Books, tools, resources…"></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Assessment</label>
        <textarea id="plan-assessment" class="tp-textarea" style="min-height:60px;" placeholder="How learning will be assessed…"></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Notes</label>
        <textarea id="plan-notes" class="tp-textarea" style="min-height:50px;" placeholder="Any additional notes…"></textarea>
      </div>
      <div style="display:flex;gap:.6rem;margin-top:.5rem;">
        <button type="submit" class="tp-btn tp-btn-primary" style="flex:1;">
          <i class="fas fa-save"></i> Save Draft
        </button>
        <button type="button" class="tp-btn tp-btn-outline" onclick="closePlanModal()">Cancel</button>
      </div>
    </form>
  </div>
</div>

<!-- Note modal -->
<div class="tp-modal-backdrop" id="note-modal">
  <div class="tp-modal-sheet">
    <div class="tp-modal-header">
      <h2 id="note-modal-title">Lesson Note</h2>
      <button class="tp-modal-close" onclick="closeNoteModal()">&times;</button>
    </div>
    <form id="note-form" onsubmit="saveNote(event)">
      <input type="hidden" id="note-id" value="0">
      <div class="tp-row-2">
        <div class="tp-form-group">
          <label class="tp-label">Class</label>
          <select id="note-class" class="tp-select" required onchange="loadSubjectsForForm('note')"></select>
        </div>
        <div class="tp-form-group">
          <label class="tp-label">Date</label>
          <input type="date" id="note-date" class="tp-input" value="<?= date('Y-m-d') ?>" required>
        </div>
      </div>
      <div class="tp-row-2">
        <div class="tp-form-group">
          <label class="tp-label">Subject</label>
          <select id="note-subject" class="tp-select"></select>
        </div>
        <div class="tp-form-group">
          <label class="tp-label">Engagement</label>
          <select id="note-engagement" class="tp-select">
            <option value="excellent">Excellent</option>
            <option value="good" selected>Good</option>
            <option value="fair">Fair</option>
            <option value="poor">Poor</option>
          </select>
        </div>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">What Was Taught</label>
        <textarea id="note-taught" class="tp-textarea" placeholder="Topics covered this lesson…" required></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Objectives Met</label>
        <textarea id="note-objectives" class="tp-textarea" style="min-height:60px;" placeholder="Which objectives were achieved…"></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Challenges</label>
        <textarea id="note-challenges" class="tp-textarea" style="min-height:60px;" placeholder="Any difficulties faced…"></textarea>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Plan for Next Lesson</label>
        <textarea id="note-next" class="tp-textarea" style="min-height:60px;" placeholder="What comes next…"></textarea>
      </div>
      <div style="display:flex;gap:.6rem;margin-top:.5rem;">
        <button type="submit" class="tp-btn tp-btn-primary" style="flex:1;"><i class="fas fa-save"></i> Save</button>
        <button type="button" class="tp-btn tp-btn-outline" onclick="closeNoteModal()">Cancel</button>
      </div>
    </form>
  </div>
</div>

<!-- Homework assign modal -->
<div class="tp-modal-backdrop" id="hw-modal">
  <div class="tp-modal-sheet">
    <div class="tp-modal-header">
      <h2 id="hw-modal-title">Assign Homework</h2>
      <button class="tp-modal-close" onclick="closeHwModal()">&times;</button>
    </div>
    <form id="hw-form" onsubmit="saveHomework(event)">
      <input type="hidden" id="hw-id" value="0">
      <div class="tp-row-2">
        <div class="tp-form-group">
          <label class="tp-label">Class</label>
          <select id="hw-class-sel" class="tp-select" required onchange="loadSubjectsForForm('hw')"></select>
        </div>
        <div class="tp-form-group">
          <label class="tp-label">Due Date</label>
          <input type="date" id="hw-due" class="tp-input" required>
        </div>
      </div>
      <div class="tp-row-2">
        <div class="tp-form-group">
          <label class="tp-label">Subject</label>
          <select id="hw-subject" class="tp-select"></select>
        </div>
        <div class="tp-form-group">
          <label class="tp-label">Max Score</label>
          <input type="number" id="hw-max-score" class="tp-input" value="10" min="1" max="100">
        </div>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Title</label>
        <input type="text" id="hw-title" class="tp-input" placeholder="Homework title…" required>
      </div>
      <div class="tp-form-group">
        <label class="tp-label">Description</label>
        <textarea id="hw-desc" class="tp-textarea" placeholder="Instructions for students…"></textarea>
      </div>
      <div class="tp-form-group">
        <label style="display:flex;align-items:center;gap:.5rem;cursor:pointer;">
          <input type="checkbox" id="hw-visible" checked>
          <span class="tp-label" style="margin:0;">Visible to parents</span>
        </label>
      </div>
      <div style="display:flex;gap:.6rem;margin-top:.5rem;">
        <button type="submit" class="tp-btn tp-btn-primary" style="flex:1;"><i class="fas fa-save"></i> Assign</button>
        <button type="button" class="tp-btn tp-btn-outline" onclick="closeHwModal()">Cancel</button>
      </div>
    </form>
  </div>
</div>

<!-- Homework tracker modal -->
<div class="tp-modal-backdrop" id="hw-track-modal">
  <div class="tp-modal-sheet">
    <div class="tp-modal-header">
      <h2 id="hw-track-title">Track Submissions</h2>
      <button class="tp-modal-close" onclick="document.getElementById('hw-track-modal').classList.remove('open')">&times;</button>
    </div>
    <div id="hw-track-content"><div class="tp-loading"><div class="tp-spinner"></div></div></div>
    <button class="tp-btn tp-btn-primary tp-btn-block" onclick="saveTracking()" style="margin-top:.8rem;">
      <i class="fas fa-save"></i> Save
    </button>
  </div>
</div>

<!-- Student detail modal -->
<div class="tp-modal-backdrop" id="student-modal">
  <div class="tp-modal-sheet">
    <div class="tp-modal-header">
      <h2 id="student-modal-title">Student Detail</h2>
      <button class="tp-modal-close" onclick="document.getElementById('student-modal').classList.remove('open')">&times;</button>
    </div>
    <div id="student-modal-content"></div>
  </div>
</div>

<script>
/* ═══════════════════════════════════════════════════════════════
   TEACHER PORTAL — SPA CONTROLLER
═══════════════════════════════════════════════════════════════ */

// ── State ──────────────────────────────────────────────────────
const S = {
  tab: '<?= $tab ?>',
  classes: [],
  subjects: [],
  today: null,
  timetable: null,
  attStudents: [],
  marksStudents: [],
  marksInfo: null,
  currentHwId: 0,
  trackStudents: [],
  noticesPage: 1,
  noticesTotal: 0,
};

// ── Utilities ──────────────────────────────────────────────────
const $ = id => document.getElementById(id);
const esc = s => String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
const fmtDate = d => d ? new Date(d+'T00:00').toLocaleDateString('en-GB',{day:'numeric',month:'short',year:'numeric'}) : '';
const fmtTime = t => { if (!t) return ''; const [h,m] = t.split(':'); const hh=+h; return `${hh>12?hh-12:hh||12}:${m} ${hh>=12?'PM':'AM'}`; };

function toast(msg, type='') {
  const el = $('tp-toast');
  el.textContent = msg;
  el.className = 'tp-toast show' + (type ? ' tp-toast-'+type : '');
  setTimeout(() => el.className = 'tp-toast', 2600);
}

async function api(endpoint, opts = {}) {
  try {
    const res = await fetch('ajax/' + endpoint, {
      headers: { 'Content-Type': 'application/json' },
      ...opts,
    });
    const text = await res.text();
    try {
      return JSON.parse(text);
    } catch {
      console.error('Non-JSON from ' + endpoint + ':', text.substring(0, 300));
      return { success: false, message: 'Server error — check PHP logs.' };
    }
  } catch (err) {
    return { success: false, message: 'Network error: ' + err.message };
  }
}

// ── Tab navigation ─────────────────────────────────────────────
const TAB_MAP = {
  today:'today', timetable:'timetable', attendance:'attendance',
  marks:'marks', assess:'assess', progress:'progress', plans:'plans', notes:'notes',
  homework:'homework', class:'class', notices:'notices', support:'support',
};
const NAV_TABS = ['today','timetable','attendance','marks'];

function openTab(name) {
  if (!TAB_MAP[name]) return;
  S.tab = name;

  document.querySelectorAll('.tp-section').forEach(s => s.classList.remove('active'));
  const sec = $('sec-'+name);
  if (sec) sec.classList.add('active');

  document.querySelectorAll('.tp-nav-btn').forEach(b => b.classList.remove('active'));
  const navBtn = $('nav-'+(NAV_TABS.includes(name) ? name : 'more'));
  if (navBtn) navBtn.classList.add('active');

  history.replaceState(null, '', '?tab=' + name);

  // Lazy-load on first open
  if (name === 'today' && !S.today)         loadToday();
  if (name === 'timetable' && !S.timetable) loadTimetable();
  if (name === 'attendance' && !S.attStudents.length) initAttendance();
  if (name === 'marks' && !S.marksStudents.length)    initMarks();
  if (name === 'assess' && !S.assessData)             initAssess();
  if (name === 'progress' && !S.progressInit)         initProgress();
  if (name === 'plans')    loadPlans();
  if (name === 'notes')    loadNotes();
  if (name === 'homework') loadHomework();
  if (name === 'class')    initMyClass();
  if (name === 'notices')  loadNotices();
  if (name === 'support')  initSupport();
}

function openMore() {
  $('tp-more-backdrop').classList.add('open');
  $('tp-more-drawer').classList.add('open');
}
function closeMore() {
  $('tp-more-backdrop').classList.remove('open');
  $('tp-more-drawer').classList.remove('open');
}

function showUserMenu() {
  const m = $('user-menu');
  m.style.display = m.style.display === 'none' ? 'block' : 'none';
}
document.addEventListener('click', e => {
  const menu = $('user-menu');
  if (!menu) return;
  if (!menu.contains(e.target) && !e.target.closest('.tp-avatar')) {
    menu.style.display = 'none';
  }
});

// ── TODAY ──────────────────────────────────────────────────────
async function loadToday() {
  const r = await api('tp_today.php');
  if (!r.success) { $('today-content').innerHTML = '<p class="tp-empty">Could not load today\'s data.</p>'; return; }
  const d = r.data;
  S.today = d;
  S.classes = d.classes || [];

  // Update notice badge
  if (d.notice_count > 0) {
    const b = $('notice-bell-badge');
    b.textContent = d.notice_count;
    b.classList.add('show');
  }

  const done = d.done_today || 0, total = d.teaching_today || 0;
  let html = `
    <div class="tp-date-banner">
      <div class="day">${esc(d.day)}</div>
      <div class="date">${esc(d.date)}</div>
      <div class="stats">
        <div><div class="stat-val">${done}/${total}</div><div class="stat-lbl">Lessons Done</div></div>
        <div><div class="stat-val">${d.classes.length}</div><div class="stat-lbl">Classes</div></div>
      </div>
    </div>`;

  // Attendance quick-action
  const pendingAtt = d.classes.filter(c => !d.attendance_done.includes(c));
  if (pendingAtt.length) {
    html += `<div class="tp-card" style="border-left:3px solid #d97706;">
      <div class="tp-card-title">Attendance Pending</div>`;
    pendingAtt.forEach(c => {
      html += `<div style="display:flex;align-items:center;justify-content:space-between;padding:.3rem 0;">
        <span>${esc(c)}</span>
        <button class="tp-btn tp-btn-outline tp-btn-sm" onclick="goTakeAttendance('${esc(c)}')">Take</button>
      </div>`;
    });
    html += `</div>`;
  }

  // Today's schedule
  if (d.slots.length) {
    html += `<div class="tp-card"><div class="tp-card-title">Today's Schedule</div>`;
    d.slots.forEach(s => {
      const dot = s.is_break ? 'break' : (s.status || 'upcoming');
      const badgeClass = `slot-badge-${dot}`;
      const label = s.is_break ? 'Break' : (s.status === 'active' ? 'Now' : s.status === 'next' ? 'Next' : s.status === 'done' ? 'Done' : '');
      html += `<div class="tp-slot-row">
        <div class="tp-slot-dot ${dot}"></div>
        <div class="tp-slot-time">${fmtTime(s.start_time)}–${fmtTime(s.end_time)}</div>
        <div class="tp-slot-info">
          <div class="subj">${esc(s.subject_name || s.period_name)}</div>
          <div class="cls">${esc(s.class_name || '')}${s.room?' · Room '+esc(s.room):''}</div>
        </div>
        ${label ? `<span class="badge ${badgeClass}" style="font-size:.7rem;">${label}</span>` : ''}
      </div>`;
    });
    html += `</div>`;
  } else {
    html += `<div class="tp-card"><div class="tp-empty"><i class="fas fa-coffee"></i>No lessons scheduled today</div></div>`;
  }

  // Homework pending marking
  if (d.homework_pending && d.homework_pending.length) {
    html += `<div class="tp-card"><div class="tp-card-title">Homework Needs Marking</div>`;
    d.homework_pending.forEach(h => {
      html += `<div class="tp-hw-row">
        <div style="display:flex;justify-content:space-between;align-items:center;">
          <div>
            <div class="tp-hw-title">${esc(h.title)}</div>
            <div class="tp-hw-meta">${esc(h.class_name)} · Due ${fmtDate(h.due_date)}</div>
          </div>
          <button class="tp-btn tp-btn-outline tp-btn-sm" onclick="openHwTracker(${h.id})">Mark</button>
        </div>
        <div class="tp-progress-bar"><div class="tp-progress-fill" style="width:${h.total_students>0?Math.round(h.submitted/h.total_students*100):0}%"></div></div>
        <div style="font-size:.72rem;color:#64748b;margin-top:3px;">${h.submitted}/${h.total_students} submitted</div>
      </div>`;
    });
    html += `</div>`;
  }

  $('today-content').innerHTML = html;
}

function goTakeAttendance(cls) {
  openTab('attendance');
  setTimeout(() => {
    const sel = $('att-class');
    if (sel) { sel.value = cls; loadAttendance(); }
  }, 150);
}

// ── TIMETABLE ──────────────────────────────────────────────────
async function loadTimetable() {
  const r = await api('tp_timetable.php');
  if (!r.success) { $('timetable-content').innerHTML = '<p class="tp-empty">Could not load timetable.</p>'; return; }
  const d = r.data;
  S.timetable = d;

  const todayDay = d.today_day; // e.g. "Mon"
  let activeDay = d.days.includes(todayDay) ? todayDay : d.days[0];

  function renderDay(day) {
    const slots = d.by_day[day] || [];
    let html = '';
    if (!slots.length) {
      html = '<p class="tp-empty" style="padding:1.5rem;">No lessons on ' + day + '</p>';
    } else {
      slots.forEach(s => {
        const isToday = day === todayDay;
        const isBrk   = s.is_break == 1 || s.is_break === true;
        html += `<div class="tp-tt-slot ${isToday?'today-slot':''} ${isBrk?'is-break':''}">
          <div class="tp-tt-time">${fmtTime(s.start_time)}<br><small>${fmtTime(s.end_time)}</small></div>
          <div class="tp-tt-body">
            <div class="subj">${esc(isBrk ? s.period_name : (s.subject_name || s.period_name))}</div>
            <div class="meta">${isBrk ? 'Break' : esc(s.class_name) + (s.room ? ' · ' + esc(s.room) : '')}</div>
          </div>
        </div>`;
      });
    }
    return html;
  }

  let pills = `<div class="tp-day-pills tp-scroll-x">`;
  d.days.forEach(day => {
    pills += `<button class="tp-day-pill ${day===activeDay?'active':''}" onclick="switchDay('${day}')">${day}</button>`;
  });
  pills += `</div><div id="tt-day-slots">${renderDay(activeDay)}</div>`;

  $('timetable-content').innerHTML = pills;

  window._ttDays = d.by_day;
  window._ttTodayDay = todayDay;
}

function switchDay(day) {
  document.querySelectorAll('.tp-day-pill').forEach(b => {
    b.classList.toggle('active', b.textContent.trim() === day);
  });
  const slots = window._ttDays[day] || [];
  const todayDay = window._ttTodayDay;
  let html = '';
  if (!slots.length) {
    html = '<p class="tp-empty" style="padding:1.5rem;">No lessons on ' + day + '</p>';
  } else {
    slots.forEach(s => {
      const isToday = day === todayDay;
      const isBrk   = s.is_break == 1 || s.is_break === true;
      html = html + `<div class="tp-tt-slot ${isToday?'today-slot':''} ${isBrk?'is-break':''}">
        <div class="tp-tt-time">${fmtTime(s.start_time)}<br><small>${fmtTime(s.end_time)}</small></div>
        <div class="tp-tt-body">
          <div class="subj">${esc(isBrk ? s.period_name : (s.subject_name || s.period_name))}</div>
          <div class="meta">${isBrk ? 'Break' : esc(s.class_name) + (s.room ? ' · ' + esc(s.room) : '')}</div>
        </div>
      </div>`;
    });
  }
  $('tt-day-slots').innerHTML = html;
}

// ── ATTENDANCE ─────────────────────────────────────────────────
async function initAttendance() {
  const r = await api('tp_today.php');
  if (r.success) {
    S.classes = r.data.classes || [];
    populateClassSelect('att-class', S.classes);
    if (S.classes.length) loadAttendance();
  }
}

function populateClassSelect(selectId, classes, all = false) {
  const sel = $(selectId);
  if (!sel) return;
  sel.innerHTML = (all ? '<option value="">All Classes</option>' : '') +
    classes.map(c => `<option value="${esc(c)}">${esc(c)}</option>`).join('');
}

async function loadAttendance() {
  const cls  = $('att-class').value;
  const date = $('att-date').value;
  if (!cls) return;
  $('att-list').innerHTML = '<div class="tp-loading"><div class="tp-spinner"></div></div>';
  $('att-save-btn').style.display = 'none';

  const r = await api(`tp_attendance.php?class=${encodeURIComponent(cls)}&date=${date}`);
  if (!r.success) { $('att-list').innerHTML = `<p class="tp-empty">${esc(r.message)}</p>`; return; }

  S.attStudents = r.data.students;
  const saved   = r.data.saved;

  $('att-saved-notice').style.display = saved ? 'block' : 'none';

  if (!S.attStudents.length) {
    $('att-list').innerHTML = '<p class="tp-empty"><i class="fas fa-users"></i>No active students in this class</p>';
    return;
  }

  let html = '';
  S.attStudents.forEach((s, i) => {
    const cur = s.att_status || '';
    html += `<div class="tp-student-row" id="att-row-${i}">
      <img class="tp-avatar-sm" src="${esc(s.photo_url)}" onerror="this.src='../assets/images/default-student.png'" alt="">
      <div class="tp-student-name">${esc(s.first_name)} ${esc(s.last_name)}</div>
      <div class="tp-att-btns">
        ${['P','A','L','E'].map(v => `<button class="tp-att-btn ${cur.toUpperCase().startsWith(v)||cur===v.toLowerCase()?'sel-'+v:''}" data-idx="${i}" data-val="${v}" onclick="setAtt(${i},'${v}')">${v}</button>`).join('')}
      </div>
    </div>`;
  });
  $('att-list').innerHTML = html;
  $('att-save-btn').style.display = 'block';
}

function setAtt(idx, val) {
  const status_map = { P:'present', A:'absent', L:'late', E:'excused' };
  S.attStudents[idx].att_status = status_map[val];
  const row = $('att-row-'+idx);
  row.querySelectorAll('.tp-att-btn').forEach(b => {
    b.classList.remove('sel-P','sel-A','sel-L','sel-E');
    if (b.dataset.val === val) b.classList.add('sel-'+val);
  });
}

function markAllPresent() {
  S.attStudents.forEach((s, i) => setAtt(i, 'P'));
  toast('All marked present');
}

async function saveAttendance() {
  const cls  = $('att-class').value;
  const date = $('att-date').value;
  const records = S.attStudents.map(s => ({
    student_id: s.id,
    status: s.att_status || 'present',
    notes: s.att_notes || '',
  }));
  const r = await api('tp_attendance.php', {
    method: 'POST',
    body: JSON.stringify({ class_name: cls, date, records }),
  });
  toast(r.message || (r.success ? 'Saved!' : 'Error'), r.success ? 'success' : 'error');
  if (r.success) $('att-saved-notice').style.display = 'block';
}

// ── MARKS ──────────────────────────────────────────────────────
async function initMarks() {
  if (!S.classes.length) {
    const r = await api('tp_today.php');
    if (r.success) S.classes = r.data.classes || [];
  }
  populateClassSelect('marks-class', S.classes);
  if (S.classes.length) loadSubjectsForMarks();
}

async function loadSubjectsForMarks() {
  const cls = $('marks-class').value;
  if (!cls) return;
  $('marks-subject').innerHTML = '<option>Loading…</option>';
  $('marks-list').innerHTML = '';
  $('marks-save-btn').style.display = 'none';

  const r = await api(`tp_class.php?class=${encodeURIComponent(cls)}`);
  if (!r.success) return;
  const subjects = r.data.subjects || [];
  $('marks-subject').innerHTML = subjects.map(s =>
    `<option value="${s.subject_id}">${esc(s.subject_name)}</option>`
  ).join('') || '<option value="">No subjects</option>';
  if (subjects.length) loadMarks();
}

async function loadMarks() {
  const cls = $('marks-class').value;
  const sid = $('marks-subject').value;
  if (!cls || !sid) return;
  $('marks-list').innerHTML = '<div class="tp-loading"><div class="tp-spinner"></div></div>';
  $('marks-save-btn').style.display = 'none';

  const r = await api(`tp_marks.php?class=${encodeURIComponent(cls)}&subject=${sid}`);
  if (!r.success) { $('marks-list').innerHTML = `<p class="tp-empty">${esc(r.message)}</p>`; return; }

  S.marksStudents = r.data.students;
  S.marksInfo     = r.data;

  const mcs = r.data.max_class_score, mes = r.data.max_exam_score;
  $('marks-meta').textContent = `Class Score: /${mcs} (${r.data.class_score_pct}%)  ·  Exam Score: /${mes} (${r.data.exam_score_pct}%)  ·  ${r.data.term} ${r.data.academic_year}`;

  if (!S.marksStudents.length) {
    $('marks-list').innerHTML = '<p class="tp-empty">No active students</p>';
    return;
  }

  let html = `<div class="tp-marks-row">
    <div class="tp-marks-hdr">Student</div>
    <div class="tp-marks-hdr">Class /${mcs}</div>
    <div class="tp-marks-hdr">Exam /${mes}</div>
    <div class="tp-marks-hdr">Grade</div>
  </div>`;

  S.marksStudents.forEach((s, i) => {
    html += `<div class="tp-marks-row">
      <div style="font-size:.85rem;font-weight:500;">${esc(s.first_name)} ${esc(s.last_name)}</div>
      <input type="number" class="tp-score-input" id="cs-${i}" value="${s.class_score||''}"
             min="0" max="${mcs}" step="0.5" onchange="updateGrade(${i})" data-idx="${i}">
      <input type="number" class="tp-score-input" id="es-${i}" value="${s.exam_score||''}"
             min="0" max="${mes}" step="0.5" onchange="updateGrade(${i})" data-idx="${i}">
      <div class="tp-grade-badge" id="grade-${i}">${esc(s.grade||'–')}</div>
    </div>`;
  });
  $('marks-list').innerHTML = html;
  $('marks-save-btn').style.display = 'block';
}

function updateGrade(i) {
  const cs = parseFloat($('cs-'+i).value) || 0;
  const es = parseFloat($('es-'+i).value) || 0;
  const info = S.marksInfo;
  if (!info) return;
  const mcs = info.max_class_score, mes = info.max_exam_score;
  const wcs = mcs > 0 ? (cs/mcs)*info.class_score_pct : 0;
  const wes = mes > 0 ? (es/mes)*info.exam_score_pct  : 0;
  const total = Math.round((wcs+wes)*10)/10;
  const badge = $('grade-'+i);
  badge.textContent = total > 0 ? total.toFixed(1)+'%' : '–';
  badge.style.background = total >= 80 ? '#dcfce7' : total >= 60 ? '#fef9c3' : total >= 40 ? '#ffedd5' : '#fee2e2';
  badge.style.color       = total >= 80 ? '#166534' : total >= 60 ? '#713f12' : total >= 40 ? '#7c2d12' : '#991b1b';
}

async function saveMarks() {
  const cls = $('marks-class').value;
  const sid = parseInt($('marks-subject').value);
  const records = S.marksStudents.map((s, i) => ({
    student_id:  s.id,
    class_score: parseFloat($('cs-'+i).value) || 0,
    exam_score:  parseFloat($('es-'+i).value) || 0,
  }));
  const r = await api('tp_marks.php', {
    method: 'POST',
    body: JSON.stringify({ class_name: cls, subject_id: sid, records }),
  });
  toast(r.message || (r.success ? 'Saved!' : 'Error'), r.success ? 'success' : 'error');
}

// ── ASSESSMENTS (SBA) ──────────────────────────────────────────
async function initAssess() {
  if (!S.classes.length) {
    const r = await api('tp_today.php');
    if (r.success) S.classes = r.data.classes || [];
  }
  populateClassSelect('assess-class', S.classes);
  if (S.classes.length) loadSubjectsForAssess();
}

async function loadSubjectsForAssess() {
  const cls = $('assess-class').value;
  if (!cls) return;
  $('assess-subject').innerHTML = '<option>Loading…</option>';
  $('assess-list').innerHTML = '';
  $('assess-save-btn').style.display = 'none';
  const r = await api(`tp_class.php?class=${encodeURIComponent(cls)}`);
  if (!r.success) return;
  const subjects = r.data.subjects || [];
  $('assess-subject').innerHTML = subjects.map(s =>
    `<option value="${s.subject_id}">${esc(s.subject_name)}</option>`).join('') || '<option value="">No subjects</option>';
  if (subjects.length) loadAssessBoard();
}

async function loadAssessBoard() {
  const cls = $('assess-class').value;
  const sid = $('assess-subject').value;
  if (!cls || !sid) return;
  $('assess-list').innerHTML = '<div class="tp-loading"><div class="tp-spinner"></div></div>';
  $('assess-save-btn').style.display = 'none';
  const r = await api(`tp_sba.php?action=board&class=${encodeURIComponent(cls)}&subject=${sid}`);
  if (!r.success) { $('assess-list').innerHTML = `<p class="tp-empty">${esc(r.message)}</p>`; return; }
  S.assessData = r.data;
  S.assessComps = (r.data.components || []).map(c => ({
    id:+c.id, component_name:c.component_name, max_score:+c.max_score, weight:+c.weight
  }));
  const w = r.data.weighting || {};
  const lvl = {lower_primary:'Lower Primary', upper_primary:'Upper Primary', jhs:'JHS', shs:'SHS'};
  $('assess-meta').innerHTML =
    `Weighting: <strong>${w.class_pct}% CA / ${w.exam_pct}% Exam</strong> · ${esc(lvl[w.level]||w.level||'')}`
    + ` · source: ${esc(w.source||'')} · ${esc(r.data.term)} ${esc(r.data.academic_year)}`;
  renderComponentsEditor();
  renderComponentPicker();
  renderAssessGrid();
}

function toggleAssessComps() {
  const wrap = $('assess-comps-wrap');
  const open = wrap.style.display !== 'none';
  wrap.style.display = open ? 'none' : 'block';
  $('assess-comps-chevron').className = open ? 'fas fa-chevron-down' : 'fas fa-chevron-up';
}

function renderComponentsEditor() {
  const comps = S.assessComps || [];
  let html = '';
  comps.forEach((c, i) => {
    html += `<div class="tp-marks-row" style="grid-template-columns:1fr 64px 56px 34px;gap:.4rem;align-items:center;">
      <input class="tp-select" style="font-size:.82rem;" value="${esc(c.component_name)}" oninput="editComp(${i},'component_name',this.value)" placeholder="Component name">
      <input type="number" class="tp-score-input" value="${c.max_score}" min="1" step="1" title="Max score" oninput="editComp(${i},'max_score',this.value)">
      <input type="number" class="tp-score-input" value="${c.weight}" min="0" step="0.5" title="Weight" oninput="editComp(${i},'weight',this.value)">
      <button class="tp-btn tp-btn-sm" style="background:#fee2e2;color:#991b1b;padding:.3rem .5rem;" onclick="removeComponentRow(${i})"><i class="fas fa-trash"></i></button>
    </div>`;
  });
  if (!comps.length) html = '<p class="tp-empty" style="padding:.4rem;">No components yet — add one.</p>';
  $('assess-comps-list').innerHTML = html;
}

function editComp(i, field, val) {
  if (!S.assessComps[i]) return;
  S.assessComps[i][field] = (field === 'component_name') ? val : (parseFloat(val) || 0);
}

function addComponentRow() {
  S.assessComps = S.assessComps || [];
  S.assessComps.push({ id:0, component_name:'', max_score:100, weight:1 });
  renderComponentsEditor();
}

function removeComponentRow(i) {
  S.assessComps.splice(i, 1);
  renderComponentsEditor();
}

async function saveComponents() {
  const cls = $('assess-class').value;
  const sid = parseInt($('assess-subject').value);
  const components = (S.assessComps || []).filter(c => (c.component_name||'').trim() !== '');
  if (!components.length) { toast('Add at least one component', 'error'); return; }
  const r = await api('tp_sba.php', {
    method:'POST',
    body: JSON.stringify({ action:'save_components', class_name:cls, subject_id:sid, components })
  });
  toast(r.message || (r.success ? 'Saved' : 'Error'), r.success ? 'success' : 'error');
  if (r.success) loadAssessBoard();
}

function renderComponentPicker() {
  const comps = (S.assessData && S.assessData.components) || [];
  $('assess-comp-pick').innerHTML = comps.map(c =>
    `<option value="${c.id}">${esc(c.component_name)} (/${(+c.max_score)})</option>`).join('')
    || '<option value="">No components</option>';
}

function renderAssessGrid() {
  const data = S.assessData;
  if (!data) return;
  const students = data.students || [];
  const cid = parseInt($('assess-comp-pick').value) || 0;
  const comp = (data.components || []).find(c => +c.id === cid);
  if (!comp) { $('assess-list').innerHTML = '<p class="tp-empty">Add a component to start.</p>'; $('assess-save-btn').style.display='none'; return; }
  if (!students.length) { $('assess-list').innerHTML = '<p class="tp-empty">No active students</p>'; $('assess-save-btn').style.display='none'; return; }
  let html = `<div class="tp-marks-row">
    <div class="tp-marks-hdr">Student</div>
    <div class="tp-marks-hdr">${esc(comp.component_name)} /${(+comp.max_score)}</div>
    <div class="tp-marks-hdr">CA Preview</div>
  </div>`;
  students.forEach((s, i) => {
    const val = (s.scores && s.scores[cid] != null) ? s.scores[cid] : '';
    html += `<div class="tp-marks-row">
      <div style="font-size:.85rem;font-weight:500;">${esc(s.first_name)} ${esc(s.last_name)}</div>
      <input type="number" class="tp-score-input" id="asc-${i}" value="${val}" min="0" max="${(+comp.max_score)}" step="0.5" onchange="onAssessInput(${i})">
      <div class="tp-grade-badge" id="ca-${i}">${s.ca_preview != null ? (+s.ca_preview).toFixed(1) : '–'}</div>
    </div>`;
  });
  $('assess-list').innerHTML = html;
  $('assess-save-btn').style.display = 'block';
}

function onAssessInput(i) {
  const data = S.assessData;
  const cid = parseInt($('assess-comp-pick').value) || 0;
  const v = parseFloat($('asc-'+i).value);
  const s = data.students[i];
  s.scores = s.scores || {};
  if (isNaN(v)) delete s.scores[cid]; else s.scores[cid] = v;
  s.ca_preview = computeCaPreview(s);
  $('ca-'+i).textContent = s.ca_preview != null ? s.ca_preview.toFixed(1) : '–';
}

function computeCaPreview(student) {
  const comps = (S.assessData && S.assessData.components) || [];
  const maxClass = (S.assessData && S.assessData.weighting && S.assessData.weighting.max_class) || 100;
  let wf = 0, tw = 0;
  comps.forEach(c => {
    const max = +c.max_score, wt = +c.weight;
    if (max <= 0 || wt <= 0) return;
    let raw = (student.scores && student.scores[+c.id] != null) ? +student.scores[+c.id] : 0;
    raw = Math.max(0, Math.min(raw, max));
    wf += (raw/max)*wt; tw += wt;
  });
  if (tw <= 0) return null;
  return Math.round((wf/tw)*maxClass*100)/100;
}

async function saveAssessScores() {
  const cls = $('assess-class').value;
  const sid = parseInt($('assess-subject').value);
  const students = (S.assessData && S.assessData.students) || [];
  const records = students.map(s => ({ student_id: s.id, scores: s.scores || {} }));
  const r = await api('tp_sba.php', {
    method:'POST',
    body: JSON.stringify({ action:'save_scores', class_name:cls, subject_id:sid, records })
  });
  toast(r.message || (r.success ? 'Saved' : 'Error'), r.success ? 'success' : 'error');
  if (r.success) loadAssessBoard();
}

// ── LESSON PLANS ───────────────────────────────────────────────
async function loadPlans() {
  const cls = $('plans-class')?.value || '';
  if (!S.classes.length) {
    const r = await api('tp_today.php');
    if (r.success) {
      S.classes  = r.data.classes || [];
      S.subjects = r.data.classes ? [] : [];
      populateClassSelect('plans-class', S.classes, true);
    }
  }
  const url = 'tp_lesson_plans.php' + (cls ? `?class=${encodeURIComponent(cls)}` : '');
  const r = await api(url);
  if (!r.success) return;
  S.classes  = r.data.classes || S.classes;
  S.subjects = r.data.subjects || [];
  populateClassSelect('plans-class', S.classes, true);

  const plans = r.data.plans || [];
  if (!plans.length) {
    $('plans-list').innerHTML = '<p class="tp-empty"><i class="fas fa-book-open"></i>No lesson plans yet</p>';
    return;
  }
  $('plans-list').innerHTML = plans.map(p => `
    <div class="tp-plan-row">
      <div class="tp-plan-body">
        <div class="tp-plan-title">${esc(p.subject_name)} — ${esc(p.class_name)}</div>
        <div class="tp-plan-meta">Week of ${fmtDate(p.week_start)} · ${esc(p.term)}</div>
        <div style="margin-top:3px;">
          <span class="badge badge-${p.status}" style="font-size:.7rem;padding:2px 7px;border-radius:6px;">${p.status}</span>
        </div>
      </div>
      <div class="tp-plan-actions">
        ${p.status==='draft' ? `<button class="tp-icon-btn" title="Edit" onclick="editPlan(${p.id})"><i class="fas fa-pen"></i></button>` : ''}
        ${p.status==='draft' ? `<button class="tp-icon-btn" title="Submit" onclick="submitPlan(${p.id})" style="color:#d97706;border-color:#d97706;"><i class="fas fa-paper-plane"></i></button>` : ''}
        <button class="tp-icon-btn" title="Delete" onclick="deletePlan(${p.id})" style="color:#dc2626;"><i class="fas fa-trash"></i></button>
      </div>
    </div>`).join('');
}

function openPlanModal(plan = null) {
  $('plan-id').value = plan?.id || 0;
  $('plan-modal-title').textContent = plan ? 'Edit Lesson Plan' : 'New Lesson Plan';
  $('plan-week').value = plan?.week_start || '';
  $('plan-objectives').value = plan?.objectives || '';
  $('plan-content').value   = plan?.content    || '';
  $('plan-methods').value   = plan?.teaching_methods || '';
  $('plan-materials').value = plan?.materials  || '';
  $('plan-assessment').value= plan?.assessment || '';
  $('plan-notes').value     = plan?.notes      || '';

  if (!S.classes.length) {
    api('tp_lesson_plans.php').then(r => {
      if (r.success) { S.classes = r.data.classes; S.subjects = r.data.subjects; }
      populateClassSelect('plan-class', S.classes);
      if (plan) { $('plan-class').value = plan.class_name; loadSubjectsForForm('plan', plan.subject_id); }
      else loadSubjectsForForm('plan');
    });
  } else {
    populateClassSelect('plan-class', S.classes);
    if (plan) { $('plan-class').value = plan.class_name; loadSubjectsForForm('plan', plan.subject_id); }
    else loadSubjectsForForm('plan');
  }
  $('plan-modal').classList.add('open');
}
function closePlanModal() { $('plan-modal').classList.remove('open'); }

async function editPlan(id) {
  const r = await api(`tp_lesson_plans.php?action=get&id=${id}`);
  if (r.success) openPlanModal(r.data);
}

async function submitPlan(id) {
  if (!confirm('Submit this plan for approval?')) return;
  const r = await api('tp_lesson_plans.php', { method:'POST', body: JSON.stringify({action:'submit', id}) });
  toast(r.message, r.success?'success':'error');
  if (r.success) loadPlans();
}

async function deletePlan(id) {
  if (!confirm('Delete this plan?')) return;
  const r = await api('tp_lesson_plans.php', { method:'POST', body: JSON.stringify({action:'delete', id}) });
  toast(r.message, r.success?'success':'error');
  if (r.success) loadPlans();
}

async function savePlan(e) {
  e.preventDefault();
  const cls  = $('plan-class').value;
  const subj = $('plan-subject');
  const subOpt = subj.options[subj.selectedIndex];
  const body = {
    id: parseInt($('plan-id').value) || 0,
    class_name: cls,
    subject_id: parseInt(subj.value) || 0,
    subject_name: subOpt?.text || '',
    week_start:  $('plan-week').value,
    objectives:  $('plan-objectives').value,
    content:     $('plan-content').value,
    teaching_methods: $('plan-methods').value,
    materials:   $('plan-materials').value,
    assessment:  $('plan-assessment').value,
    notes:       $('plan-notes').value,
  };
  const r = await api('tp_lesson_plans.php', { method:'POST', body: JSON.stringify(body) });
  toast(r.message, r.success?'success':'error');
  if (r.success) { closePlanModal(); loadPlans(); }
}

// ── LESSON NOTES ───────────────────────────────────────────────
async function loadNotes() {
  const cls = $('notes-class')?.value || '';
  if (!S.classes.length) {
    const r = await api('tp_lesson_notes.php');
    if (r.success) { S.classes = r.data.classes; S.subjects = r.data.subjects; }
  }
  populateClassSelect('notes-class', S.classes, true);
  const url = 'tp_lesson_notes.php' + (cls ? `?class=${encodeURIComponent(cls)}` : '');
  const r = await api(url);
  if (!r.success) return;
  S.classes  = r.data.classes  || S.classes;
  S.subjects = r.data.subjects || S.subjects;
  populateClassSelect('notes-class', S.classes, true);

  const notes = r.data.notes || [];
  if (!notes.length) {
    $('notes-list').innerHTML = '<p class="tp-empty"><i class="fas fa-pencil-alt"></i>No lesson notes yet</p>';
    return;
  }
  const engIcon = { excellent:'😄', good:'🙂', fair:'😐', poor:'😟' };
  $('notes-list').innerHTML = notes.map(n => `
    <div class="tp-plan-row">
      <div class="tp-plan-body">
        <div class="tp-plan-title">${esc(n.subject_name)} — ${esc(n.class_name)}</div>
        <div class="tp-plan-meta">${fmtDate(n.lesson_date)} ${n.period_name?'· '+esc(n.period_name):''}</div>
        <div style="font-size:.78rem;margin-top:2px;">${engIcon[n.student_engagement]||''} ${esc(n.student_engagement)}</div>
      </div>
      <div class="tp-plan-actions">
        <button class="tp-icon-btn" onclick="editNote(${n.id})"><i class="fas fa-pen"></i></button>
        <button class="tp-icon-btn" onclick="deleteNote(${n.id})" style="color:#dc2626;"><i class="fas fa-trash"></i></button>
      </div>
    </div>`).join('');
}

function openNoteModal(note = null) {
  $('note-id').value = note?.id || 0;
  $('note-modal-title').textContent = note ? 'Edit Lesson Note' : 'New Lesson Note';
  $('note-date').value = note?.lesson_date || '<?= date('Y-m-d') ?>';
  $('note-taught').value      = note?.what_was_taught    || '';
  $('note-objectives').value  = note?.objectives_met     || '';
  $('note-challenges').value  = note?.challenges         || '';
  $('note-next').value        = note?.next_lesson_plan   || '';
  $('note-engagement').value  = note?.student_engagement || 'good';

  populateClassSelect('note-class', S.classes);
  if (note) { $('note-class').value = note.class_name; loadSubjectsForForm('note', note.subject_id); }
  else loadSubjectsForForm('note');
  $('note-modal').classList.add('open');
}
function closeNoteModal() { $('note-modal').classList.remove('open'); }

async function editNote(id) {
  const r = await api(`tp_lesson_notes.php?action=get&id=${id}`);
  if (r.success) openNoteModal(r.data);
}
async function deleteNote(id) {
  if (!confirm('Delete this note?')) return;
  const r = await api('tp_lesson_notes.php', { method:'POST', body: JSON.stringify({action:'delete', id}) });
  toast(r.message, r.success?'success':'error');
  if (r.success) loadNotes();
}
async function saveNote(e) {
  e.preventDefault();
  const subj = $('note-subject');
  const subOpt = subj.options[subj.selectedIndex];
  const body = {
    id: parseInt($('note-id').value)||0,
    class_name:  $('note-class').value,
    subject_id:  parseInt(subj.value)||0,
    subject_name: subOpt?.text||'',
    lesson_date: $('note-date').value,
    what_was_taught:    $('note-taught').value,
    objectives_met:     $('note-objectives').value,
    student_engagement: $('note-engagement').value,
    challenges:         $('note-challenges').value,
    next_lesson_plan:   $('note-next').value,
  };
  const r = await api('tp_lesson_notes.php', { method:'POST', body: JSON.stringify(body) });
  toast(r.message, r.success?'success':'error');
  if (r.success) { closeNoteModal(); loadNotes(); }
}

// ── HOMEWORK ───────────────────────────────────────────────────
async function loadHomework() {
  const cls = $('hw-class')?.value || '';
  if (!S.classes.length) {
    const r = await api('tp_homework.php');
    if (r.success) { S.classes = r.data.classes; S.subjects = r.data.subjects; }
  }
  populateClassSelect('hw-class', S.classes, true);
  const url = 'tp_homework.php' + (cls ? `?class=${encodeURIComponent(cls)}` : '');
  const r = await api(url);
  if (!r.success) return;
  S.classes  = r.data.classes  || S.classes;
  S.subjects = r.data.subjects || S.subjects;
  populateClassSelect('hw-class', S.classes, true);

  const list = r.data.homework || [];
  if (!list.length) {
    $('hw-list').innerHTML = '<p class="tp-empty"><i class="fas fa-tasks"></i>No homework assigned yet</p>';
    return;
  }
  $('hw-list').innerHTML = list.map(h => {
    const pct = h.total_students > 0 ? Math.round(h.submitted / h.total_students * 100) : 0;
    return `<div class="tp-hw-row">
      <div style="display:flex;justify-content:space-between;align-items:flex-start;">
        <div>
          <div class="tp-hw-title">${esc(h.title)}</div>
          <div class="tp-hw-meta">${esc(h.class_name)} · ${esc(h.subject_name)} · Due ${fmtDate(h.due_date)}</div>
          <div style="margin-top:2px;">
            <span class="badge badge-${h.status}" style="font-size:.68rem;padding:2px 6px;border-radius:5px;">${h.status}</span>
            ${h.is_visible_to_parents ? '<span style="font-size:.68rem;color:#16a34a;margin-left:4px;"><i class="fas fa-eye"></i> Parents</span>' : ''}
          </div>
        </div>
        <div style="display:flex;gap:.3rem;flex-shrink:0;">
          <button class="tp-icon-btn" title="Track" onclick="openHwTracker(${h.id})"><i class="fas fa-list-check"></i></button>
          ${h.status==='active'?`<button class="tp-icon-btn" title="Close" onclick="closeHomework(${h.id})" style="color:#d97706;"><i class="fas fa-lock"></i></button>`:''}
          <button class="tp-icon-btn" title="Delete" onclick="deleteHomework(${h.id})" style="color:#dc2626;"><i class="fas fa-trash"></i></button>
        </div>
      </div>
      <div class="tp-progress-bar"><div class="tp-progress-fill" style="width:${pct}%"></div></div>
      <div style="font-size:.72rem;color:#64748b;margin-top:3px;">${h.submitted}/${h.total_students} submitted · ${h.marked} marked</div>
    </div>`;
  }).join('');
}

function openHwModal(hw = null) {
  $('hw-id').value = hw?.id || 0;
  $('hw-modal-title').textContent = hw ? 'Edit Homework' : 'Assign Homework';
  $('hw-title').value     = hw?.title       || '';
  $('hw-desc').value      = hw?.description || '';
  $('hw-due').value       = hw?.due_date    || '';
  $('hw-max-score').value = hw?.max_score   || 10;
  $('hw-visible').checked = hw ? hw.is_visible_to_parents == 1 : true;

  populateClassSelect('hw-class-sel', S.classes);
  if (hw) { $('hw-class-sel').value = hw.class_name; loadSubjectsForForm('hw', hw.subject_id); }
  else loadSubjectsForForm('hw');
  $('hw-modal').classList.add('open');
}
function closeHwModal() { $('hw-modal').classList.remove('open'); }

async function saveHomework(e) {
  e.preventDefault();
  const subj = $('hw-subject');
  const subOpt = subj.options[subj.selectedIndex];
  const body = {
    id: parseInt($('hw-id').value)||0,
    class_name:  $('hw-class-sel').value,
    subject_id:  parseInt(subj.value)||0,
    subject_name: subOpt?.text||'',
    title:       $('hw-title').value,
    description: $('hw-desc').value,
    due_date:    $('hw-due').value,
    assigned_date: '<?= date('Y-m-d') ?>',
    max_score:   parseInt($('hw-max-score').value)||10,
    is_visible_to_parents: $('hw-visible').checked ? 1 : 0,
  };
  const r = await api('tp_homework.php', { method:'POST', body: JSON.stringify(body) });
  toast(r.message, r.success?'success':'error');
  if (r.success) { closeHwModal(); loadHomework(); }
}
async function deleteHomework(id) {
  if (!confirm('Delete this homework?')) return;
  const r = await api('tp_homework.php', { method:'POST', body: JSON.stringify({action:'delete', id}) });
  toast(r.message, r.success?'success':'error');
  if (r.success) loadHomework();
}
async function closeHomework(id) {
  const r = await api('tp_homework.php', { method:'POST', body: JSON.stringify({action:'close', id}) });
  toast(r.message, r.success?'success':'error');
  if (r.success) loadHomework();
}

async function openHwTracker(hwId) {
  S.currentHwId = hwId;
  $('hw-track-content').innerHTML = '<div class="tp-loading"><div class="tp-spinner"></div></div>';
  $('hw-track-modal').classList.add('open');

  const r = await api(`tp_homework_track.php?homework_id=${hwId}`);
  if (!r.success) { $('hw-track-content').innerHTML = `<p class="tp-empty">${esc(r.message)}</p>`; return; }

  const hw = r.data.homework;
  S.trackStudents = r.data.students;
  $('hw-track-title').textContent = hw.title;

  const statuses = ['pending','submitted','missing','excused'];
  let html = `<div style="font-size:.78rem;color:#64748b;margin-bottom:.6rem;">${esc(hw.class_name)} · Due ${fmtDate(hw.due_date)} · Max ${hw.max_score}</div>`;
  S.trackStudents.forEach((s, i) => {
    html += `<div style="padding:.55rem 0;border-bottom:1px solid #e2e8f0;">
      <div style="display:flex;align-items:center;gap:.6rem;margin-bottom:.35rem;">
        <img src="${esc(s.photo_url)}" style="width:32px;height:32px;border-radius:50%;object-fit:cover;" onerror="this.src='../assets/images/default-student.png'">
        <span style="flex:1;font-weight:500;font-size:.88rem;">${esc(s.first_name)} ${esc(s.last_name)}</span>
        <input type="number" id="trk-score-${i}" value="${s.score??''}" min="0" max="${hw.max_score}" step="0.5"
               style="width:65px;border:1px solid #e2e8f0;border-radius:6px;padding:3px 6px;font-size:.82rem;" placeholder="Score">
      </div>
      <div style="display:flex;gap:4px;">
        ${statuses.map(st => `<button class="tp-btn tp-btn-sm ${s.sub_status===st?'tp-btn-primary':'tp-btn-outline'}" id="trk-st-${i}-${st}"
          onclick="setTrackStatus(${i},'${st}')" style="flex:1;padding:.25rem .3rem;font-size:.7rem;">${st}</button>`).join('')}
      </div>
      <div style="margin-top:.3rem;">
        <input type="text" id="trk-comment-${i}" value="${esc(s.teacher_comment)}"
               style="width:100%;border:1px solid #e2e8f0;border-radius:6px;padding:.3rem .5rem;font-size:.8rem;" placeholder="Comment (optional)">
      </div>
    </div>`;
  });
  $('hw-track-content').innerHTML = html;
}

function setTrackStatus(idx, status) {
  S.trackStudents[idx].sub_status = status;
  ['pending','submitted','missing','excused'].forEach(st => {
    const btn = $(`trk-st-${idx}-${st}`);
    if (!btn) return;
    btn.className = 'tp-btn tp-btn-sm ' + (st === status ? 'tp-btn-primary' : 'tp-btn-outline');
    btn.style.flex = '1'; btn.style.padding = '.25rem .3rem'; btn.style.fontSize = '.7rem';
  });
}

async function saveTracking() {
  const records = S.trackStudents.map((s, i) => ({
    student_id:     s.student_id,
    status:         s.sub_status || 'pending',
    score:          $(`trk-score-${i}`)?.value || null,
    teacher_comment: $(`trk-comment-${i}`)?.value || '',
  }));
  const r = await api('tp_homework_track.php', {
    method: 'POST',
    body: JSON.stringify({ homework_id: S.currentHwId, records }),
  });
  toast(r.message, r.success?'success':'error');
  if (r.success) {
    $('hw-track-modal').classList.remove('open');
    loadHomework();
    loadToday();
  }
}

// ── MY CLASSES ─────────────────────────────────────────────────
async function initMyClass() {
  if (!S.classes.length) {
    const r = await api('tp_today.php');
    if (r.success) S.classes = r.data.classes || [];
  }
  populateClassSelect('class-sel', S.classes);
  if (S.classes.length) loadMyClass();
}

function onClassSelChange() {
  const subSel = $('class-subject-sel');
  if (subSel) subSel.innerHTML = '<option value="">All Subjects</option>';
  loadMyClass();
}

async function loadMyClass() {
  const cls = $('class-sel').value;
  const sid = $('class-subject-sel')?.value || '';
  if (!cls) return;
  $('class-content').innerHTML = '<div class="tp-loading"><div class="tp-spinner"></div></div>';

  const url = `tp_class.php?class=${encodeURIComponent(cls)}` + (sid ? `&subject=${sid}` : '');
  const r = await api(url);
  if (!r.success) { $('class-content').innerHTML = `<p class="tp-empty">${esc(r.message)}</p>`; return; }

  const d = r.data;
  populateClassSelect('class-sel', d.classes);
  $('class-sel').value = cls;

  // Repopulate subject dropdown preserving current selection
  const subSel = $('class-subject-sel');
  if (subSel) {
    const curVal = subSel.value;
    subSel.innerHTML = '<option value="">All Subjects</option>' +
      (d.subjects || []).map(s => `<option value="${s.subject_id}">${esc(s.subject_name)}</option>`).join('');
    if (curVal) subSel.value = curVal;
  }

  let html = `<div class="tp-card">
    <div class="tp-card-title">${esc(cls)} · ${d.students.length} Students <span class="badge" style="background:#eef2ff;color:#4f46e5;">${esc(d.term)}</span></div>`;

  if (!d.students.length) {
    html += '<p class="tp-empty">No active students</p>';
  } else {
    d.students.forEach(s => {
      const pct = s.att_pct;
      const attCls = pct === null ? '' : (pct >= 80 ? 'att-high' : pct >= 60 ? 'att-mid' : 'att-low');
      html += `<div class="tp-student-card" onclick="showStudentDetail(${JSON.stringify(s).replace(/"/g,'&quot;')}, ${JSON.stringify(d.subjects).replace(/"/g,'&quot;')})">
        <img src="${esc(s.photo_url)}" onerror="this.src='../assets/images/default-student.png'" alt="">
        <div class="tp-student-info">
          <div class="name">${esc(s.first_name)} ${esc(s.last_name)}</div>
          <div class="meta">ID: ${esc(s.student_id||'')} · ${esc(s.gender||'')}</div>
        </div>
        ${pct!==null ? `<span class="tp-att-pill ${attCls}">${pct}% att.</span>` : ''}
      </div>`;
    });
  }
  html += '</div>';
  $('class-content').innerHTML = html;
}

function showStudentDetail(student, subjects) {
  $('student-modal-title').textContent = student.first_name + ' ' + student.last_name;
  let html = `<div style="display:flex;gap:1rem;align-items:flex-start;margin-bottom:1rem;">
    <img src="${esc(student.photo_url)}" style="width:72px;height:72px;border-radius:50%;object-fit:cover;" onerror="this.src='../assets/images/default-student.png'">
    <div>
      <div style="font-weight:700;">${esc(student.first_name)} ${esc(student.last_name)}</div>
      <div style="font-size:.82rem;color:#64748b;">ID: ${esc(student.student_id||'')}</div>
      <div style="font-size:.82rem;color:#64748b;">${esc(student.gender||'')}${student.date_of_birth?' · '+fmtDate(student.date_of_birth):''}</div>
      ${student.parent_name?`<div style="font-size:.78rem;color:#64748b;margin-top:3px;"><i class="fas fa-user-friends"></i> ${esc(student.parent_name)}</div>`:''}
      ${student.parent_phone?`<a href="tel:${esc(student.parent_phone)}" style="font-size:.78rem;color:#4f46e5;"><i class="fas fa-phone"></i> ${esc(student.parent_phone)}</a>`:''}
    </div>
  </div>`;

  html += `<div style="margin-bottom:.8rem;">
    <div style="font-size:.78rem;font-weight:700;color:#64748b;text-transform:uppercase;margin-bottom:.4rem;">Attendance (last 30 days)</div>
    <div style="display:flex;gap:.8rem;flex-wrap:wrap;">
      <span style="font-size:.85rem;"><span style="font-weight:700;color:#16a34a;">${student.att_present}</span> Present</span>
      <span style="font-size:.85rem;"><span style="font-weight:700;color:#dc2626;">${student.att_absent}</span> Absent</span>
      <span style="font-size:.85rem;"><span style="font-weight:700;color:#d97706;">${student.att_late}</span> Late</span>
      ${student.att_pct!==null?`<span style="font-size:.85rem;font-weight:600;color:#4f46e5;">${student.att_pct}%</span>`:''}
    </div>
  </div>`;

  if (subjects.length) {
    html += `<div><div style="font-size:.78rem;font-weight:700;color:#64748b;text-transform:uppercase;margin-bottom:.4rem;">Scores (current term)</div>`;
    subjects.forEach(subj => {
      const sc = (student.scores||{})[subj.subject_id];
      html += `<div style="display:flex;justify-content:space-between;padding:.3rem 0;border-bottom:1px solid #f1f5f9;">
        <span style="font-size:.85rem;">${esc(subj.subject_name)}</span>
        ${sc ? `<span style="font-size:.85rem;font-weight:600;">${sc.total}% <span style="color:#64748b;font-size:.78rem;">${esc(sc.grade)}</span></span>` : '<span style="font-size:.78rem;color:#94a3b8;">No score</span>'}
      </div>`;
    });
    html += '</div>';
  }

  $('student-modal-content').innerHTML = html;
  $('student-modal').classList.add('open');
}

// ── NOTICES ────────────────────────────────────────────────────
let _noticesLoaded = false;
async function loadNotices(reset = true) {
  if (reset) { S.noticesPage = 1; _noticesLoaded = false; }
  const r = await api(`tp_notices.php?page=${S.noticesPage}`);
  if (!r.success) return;
  const notices = r.data.notices || [];
  S.noticesTotal = r.data.total;

  if (reset) $('notices-list').innerHTML = '';

  if (!notices.length && reset) {
    $('notices-list').innerHTML = '<p class="tp-empty"><i class="fas fa-bullhorn"></i>No announcements yet</p>';
    $('notices-more-btn').style.display = 'none';
    return;
  }

  const roleLabel = { all:'All Staff', tutor:'Teachers', admin:'Admin' };
  notices.forEach(n => {
    const div = document.createElement('div');
    div.className = 'tp-notice-row';
    div.innerHTML = `
      <div class="tp-notice-title">${esc(n.title)}</div>
      <div class="tp-notice-body">${esc(n.message).substring(0,200)}${n.message.length>200?'…':''}</div>
      <div class="tp-notice-date">${esc(n.author)} · ${new Date(n.created_at).toLocaleDateString('en-GB',{day:'numeric',month:'short',year:'numeric'})}</div>`;
    $('notices-list').appendChild(div);
  });

  const moreBtn = $('notices-more-btn');
  const shown   = S.noticesPage * 20;
  moreBtn.style.display = shown < S.noticesTotal ? 'block' : 'none';
}
function loadMoreNotices() { S.noticesPage++; loadNotices(false); }

// ── Shared: populate subject selects per form ───────────────────
function loadSubjectsForForm(form, selectedId = null) {
  const classMap = { plan:'plan-class', note:'note-class', hw:'hw-class-sel' };
  const subMap   = { plan:'plan-subject', note:'note-subject', hw:'hw-subject' };
  const cls  = $(classMap[form])?.value || '';
  const sel  = $(subMap[form]);
  if (!sel) return;

  const filtered = S.subjects.filter(s => s.class_name === cls);
  sel.innerHTML = filtered.length
    ? filtered.map(s => `<option value="${s.subject_id}" ${selectedId==s.subject_id?'selected':''}>${esc(s.subject_name)}</option>`).join('')
    : '<option value="">No subjects assigned</option>';
}

// ── PWA install prompt ──────────────────────────────────────────
let _deferredInstall = null;
window.addEventListener('beforeinstallprompt', e => {
  e.preventDefault();
  _deferredInstall = e;
  const bar = $('tp-install-bar');
  if (bar) bar.classList.add('show');
});
$('tp-install-btn')?.addEventListener('click', async () => {
  if (!_deferredInstall) return;
  _deferredInstall.prompt();
  const { outcome } = await _deferredInstall.userChoice;
  if (outcome === 'accepted') $('tp-install-bar').remove();
  _deferredInstall = null;
});

// ── Offline detection ──────────────────────────────────────────
function updateOnlineStatus() {
  const banner = $('tp-offline-banner');
  if (banner) banner.classList.toggle('show', !navigator.onLine);
}
window.addEventListener('online',  updateOnlineStatus);
window.addEventListener('offline', updateOnlineStatus);
updateOnlineStatus();

// ── Service worker registration ────────────────────────────────
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('sw.js').catch(() => {});
}

// ── STUDENT SUPPORT ────────────────────────────────────────────
let _supportData  = null;
let _supportTier  = 'all';

const TIER_LABEL = { critical:'Critical', atrisk:'At Risk', monitor:'Monitor', ontrack:'On Track', nodata:'No Data' };
const TIER_COLOR = { critical:'#dc2626', atrisk:'#d97706', monitor:'#2563eb', ontrack:'#16a34a', nodata:'#94a3b8' };
const TIER_BG    = { critical:'#fef2f2', atrisk:'#fffbeb', monitor:'#eff6ff', ontrack:'#f0fdf4', nodata:'#f8fafc' };

async function initSupport() {
  // Populate class select once
  const sel = $('support-class');
  if (sel && !sel.options.length) {
    (S.classes || []).forEach(c => {
      const o = document.createElement('option');
      o.value = o.textContent = c;
      sel.appendChild(o);
    });
  }
  await loadSupport();
}

async function loadSupport() {
  const cls = $('support-class')?.value || '';
  $('support-list').innerHTML = '<div class="tp-loading"><div class="tp-spinner"></div></div>';
  const r = await api('tp_atrisk.php' + (cls ? '?class=' + encodeURIComponent(cls) : ''));
  if (!r.success) {
    $('support-list').innerHTML = '<p class="tp-empty">Could not load student data.</p>';
    return;
  }
  _supportData = r.data;
  // Sync class select if server changed it
  if (r.data.class_name && $('support-class')) {
    $('support-class').value = r.data.class_name;
  }
  renderSupport();
}

function showIntTab(tier) {
  _supportTier = tier;
  document.querySelectorAll('.tp-tier-tab').forEach(b => {
    b.classList.toggle('active', b.dataset.tier === tier);
  });
  renderSupport();
}

function renderSupport() {
  if (!_supportData) return;
  const students = _supportData.students || [];
  const filtered = _supportTier === 'all'
    ? students.filter(s => s.tier !== 'ontrack' && s.tier !== 'nodata')
    : students.filter(s => s.tier === _supportTier);

  if (!filtered.length) {
    $('support-list').innerHTML = `<div class="tp-card"><p class="tp-empty"><i class="fas fa-check-circle" style="color:#16a34a"></i>${
      _supportTier === 'all' ? ' No students need attention right now.' : ' No students in this tier.'
    }</p></div>`;
    return;
  }

  let html = '';
  filtered.forEach(s => {
    const color = TIER_COLOR[s.tier] || '#94a3b8';
    const bg    = TIER_BG[s.tier]    || '#f8fafc';
    const label = TIER_LABEL[s.tier] || s.tier;
    html += `<div class="tp-card" style="border-left:3px solid ${color};background:${bg};margin-bottom:.5rem;cursor:pointer;" onclick="openIntModal(${s.id},'${esc(s.name)}','${esc(_supportData.class_name)}')">
      <div style="display:flex;align-items:center;gap:.7rem;">
        <img src="${esc(s.photo_url)}" style="width:38px;height:38px;border-radius:50%;object-fit:cover;flex-shrink:0;" onerror="this.src='../../assets/images/default-student.png'">
        <div style="flex:1;min-width:0;">
          <div style="font-weight:700;font-size:.9rem;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">${esc(s.name)}</div>
          <div style="font-size:.75rem;color:#64748b;">${esc(_supportData.class_name || '')}</div>
        </div>
        <span style="font-size:.72rem;font-weight:700;color:${color};white-space:nowrap;padding:.2rem .5rem;border-radius:12px;border:1px solid ${color};">${label}</span>
      </div>
      <div style="display:flex;gap:.75rem;margin-top:.5rem;flex-wrap:wrap;">
        ${s.score_pct !== null ? `<span style="font-size:.75rem;color:#475569;"><i class="fas fa-star" style="color:#f59e0b;margin-right:2px;"></i>${s.score_pct}% avg</span>` : ''}
        ${s.att_pct   !== null ? `<span style="font-size:.75rem;color:#475569;"><i class="fas fa-user-check" style="color:#10b981;margin-right:2px;"></i>${s.att_pct}% att</span>` : ''}
        ${s.hw_pct    !== null ? `<span style="font-size:.75rem;color:#475569;"><i class="fas fa-tasks" style="color:#8b5cf6;margin-right:2px;"></i>${s.hw_pct}% hw</span>` : ''}
        ${s.open_interventions > 0 ? `<span style="font-size:.75rem;color:#dc2626;"><i class="fas fa-flag" style="margin-right:2px;"></i>${s.open_interventions} open note${s.open_interventions>1?'s':''}</span>` : ''}
      </div>
    </div>`;
  });
  $('support-list').innerHTML = html;
}

function openIntModal(studentId, studentName, className) {
  $('int-student-id').value  = studentId;
  $('int-class-name').value  = className;
  $('int-student-name').textContent = studentName;
  $('int-modal-title').textContent  = 'Log Intervention — ' + studentName;
  $('int-note').value    = '';
  $('int-action').value  = '';
  $('int-followup').value = '';
  $('int-type').value    = 'academic';
  $('int-visible').checked = true;
  $('int-history').style.display = 'none';
  $('int-history-list').innerHTML = '';
  $('int-modal').classList.add('open');
  loadInterventionHistory(studentId);
}

function closeIntModal() {
  $('int-modal').classList.remove('open');
}

async function loadInterventionHistory(studentId) {
  const r = await api('tp_interventions.php?student_id=' + studentId);
  if (!r.success || !r.data.interventions.length) return;
  const items = r.data.interventions;
  $('int-history').style.display = 'block';
  $('int-history-list').innerHTML = items.map(i => {
    const typeColors = { academic:'#3b82f6', attendance:'#d97706', behaviour:'#dc2626', general:'#6b7280' };
    const col = typeColors[i.type] || '#6b7280';
    const statusBadge = i.status === 'resolved'
      ? `<span style="font-size:.68rem;color:#16a34a;margin-left:.4rem;">Resolved</span>`
      : i.status === 'monitoring'
        ? `<span style="font-size:.68rem;color:#d97706;margin-left:.4rem;">Monitoring</span>`
        : '';
    return `<div style="padding:.5rem 0;border-bottom:1px solid #f1f5f9;">
      <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:2px;">
        <span style="font-size:.72rem;font-weight:700;color:${col};text-transform:capitalize;">${i.type}</span>
        <div style="display:flex;align-items:center;gap:.3rem;">
          ${statusBadge}
          ${i.status !== 'resolved' ? `<button onclick="updateIntStatus(${i.id},'resolved')" style="font-size:.68rem;background:none;border:1px solid #d1d5db;border-radius:8px;padding:.1rem .4rem;cursor:pointer;color:#64748b;">Resolve</button>` : ''}
          <span style="font-size:.68rem;color:#94a3b8;">${new Date(i.created_at).toLocaleDateString('en-GB',{day:'numeric',month:'short'})}</span>
        </div>
      </div>
      <div style="font-size:.82rem;color:#374151;">${esc(i.note)}</div>
      ${i.visible_to_parent ? '<div style="font-size:.68rem;color:#6366f1;margin-top:2px;"><i class="fas fa-eye" style="margin-right:2px;"></i>Visible to parent</div>' : ''}
    </div>`;
  }).join('');
}

async function updateIntStatus(id, status) {
  const r = await api('tp_interventions.php', {
    method: 'POST',
    body: JSON.stringify({ action: 'update_status', id, status }),
  });
  showToast(r.message || (r.success ? 'Updated.' : 'Failed.'));
  if (r.success) {
    const sid = parseInt($('int-student-id').value);
    if (sid) loadInterventionHistory(sid);
    loadSupport();
  }
}

async function saveIntervention(e) {
  e.preventDefault();
  const body = {
    student_id:        parseInt($('int-student-id').value),
    class_name:        $('int-class-name').value,
    type:              $('int-type').value,
    note:              $('int-note').value.trim(),
    action_taken:      $('int-action').value.trim(),
    follow_up_date:    $('int-followup').value,
    visible_to_parent: $('int-visible').checked ? 1 : 0,
  };
  if (!body.note) { showToast('Note is required.'); return; }
  const r = await api('tp_interventions.php', { method: 'POST', body: JSON.stringify(body) });
  showToast(r.message || (r.success ? 'Saved.' : 'Failed.'));
  if (r.success) {
    $('int-note').value   = '';
    $('int-action').value = '';
    loadInterventionHistory(body.student_id);
    loadSupport();
  }
}

// ── PROGRESS ANALYTICS ─────────────────────────────────────────
const PROG = { series1:'#4f46e5', series1Soft:'rgba(79,70,229,.14)', series2:'#f5a200',
               grid:'#e5e7eb', muted:'#94a3b8', ink:'#1e293b' };
const PROG_GRADE = { A:'#0ca30c', B:'#1baf7a', C:'#eda100', D:'#eb6834', E:'#e34948', W:'#b23b3b' };
let progCharts = {};

async function initProgress() {
  const r = await api('tp_progress.php?action=meta');
  if (!r.success) { $('prog-meta').textContent = r.message || 'Progress is not available.'; return; }
  S.progressInit = true;
  S.progMeta = r.data;
  // Term selector — current term first.
  const terms = r.data.terms || [];
  $('prog-term').innerHTML = '<option value="">All terms</option>' +
    terms.map(t => `<option value="${esc(t)}"${t===r.data.current_term?' selected':''}>${esc(t)}</option>`).join('');
  // Class selector — the teacher's own classes.
  $('prog-class').innerHTML = (r.data.classes || [])
    .map(c => `<option value="${esc(c)}">${esc(c)}</option>`).join('');
  if (!r.data.classes || !r.data.classes.length) {
    $('prog-meta').textContent = 'You have no classes assigned yet.';
    return;
  }
  progLoad();
}

function progOnLevel() {
  const lvl = $('prog-level').value;
  $('prog-class').style.display   = (lvl === 'class' || lvl === 'student') ? '' : 'none';
  $('prog-student').style.display = (lvl === 'student') ? '' : 'none';
  if (lvl === 'student') progLoadStudents();
  else progLoad();
}
function progOnClass() {
  if ($('prog-level').value === 'student') progLoadStudents();
  else progLoad();
}
async function progLoadStudents() {
  const cls = $('prog-class').value;
  const sel = $('prog-student');
  if (!cls) { sel.innerHTML = '<option value="">Select class…</option>'; return; }
  sel.innerHTML = '<option value="">Loading…</option>';
  const r = await api('tp_progress.php?action=students&class=' + encodeURIComponent(cls));
  const list = (r.data && r.data.students) || [];
  sel.innerHTML = '<option value="">Select student…</option>' +
    list.map(s => `<option value="${s.id}">${esc(s.label)}</option>`).join('');
}

function progParams() {
  const lvl = $('prog-level').value, term = $('prog-term').value;
  let q = 'action=dashboard&level=' + lvl;
  if (term) q += '&term=' + encodeURIComponent(term);
  if (lvl === 'class' || lvl === 'student') {
    const c = $('prog-class').value; if (c) q += '&classes=' + encodeURIComponent(c);
  }
  if (lvl === 'student') {
    const s = $('prog-student').value; if (s) q += '&student_id=' + s;
  }
  return q;
}

async function progLoad() {
  const lvl = $('prog-level').value;
  if ((lvl === 'class' || lvl === 'student') && !$('prog-class').value) {
    $('prog-meta').textContent = 'Pick a class.'; return;
  }
  if (lvl === 'student' && !$('prog-student').value) {
    $('prog-meta').textContent = 'Pick a student.'; return;
  }
  $('prog-meta').textContent = 'Loading…';
  const r = await api('tp_progress.php?' + progParams());
  if (!r.success) { $('prog-meta').textContent = r.message || 'Could not load.'; return; }
  const d = r.data;
  if (d.no_classes) { $('prog-meta').textContent = 'You have no classes assigned yet.'; return; }
  $('prog-meta').textContent = (lvl === 'student' && d.student)
    ? d.student.name + ' · ' + (d.student.class || '')
    : (lvl === 'school' ? 'Across your classes' : $('prog-class').value);
  $('prog-trend-title').textContent = lvl === 'student' ? 'This student vs class average' : 'Performance trend';
  $('prog-table-title').textContent = lvl === 'school' ? 'By class' : lvl === 'class' ? 'By student' : 'By subject';

  try { progKpis(d.kpis, lvl); } catch(e){ console.error(e); }
  try { progTrend(d.trend); } catch(e){ console.error(e); }
  try { progSubjects(d.subjects, lvl); } catch(e){ console.error(e); }
  try { progTable(d.table, lvl); } catch(e){ console.error(e); }
}

function progKpis(k, lvl) {
  const tiles = [
    ['Average', k.avg_score==null?'—':(+k.avg_score).toFixed(1)],
    ['Pass rate', k.pass_rate==null?'—':(+k.pass_rate).toFixed(0)+'%'],
    [lvl==='student'?'Best':'Top', k.top_score==null?'—':(+k.top_score).toFixed(1)],
    ['Coverage', k.coverage_pct==null?'—':(+k.coverage_pct).toFixed(0)+'%'],
  ];
  $('prog-kpis').innerHTML = tiles.map(t =>
    `<div class="prog-kpi"><div class="v">${esc(t[1])}</div><div class="l">${esc(t[0])}</div></div>`).join('');
}

function progMake(id, cfg) {
  if (progCharts[id]) progCharts[id].destroy();
  progCharts[id] = new Chart($(id).getContext('2d'), cfg);
}
const PROG_AXES = { x:{grid:{display:false},ticks:{color:PROG.muted,font:{size:10}}},
                    y:{beginAtZero:true,suggestedMax:100,grid:{color:PROG.grid},ticks:{color:PROG.muted,font:{size:10}}} };

function progTrend(tr) {
  const ds = (tr.series||[]).map((s,i) => ({
    label:s.name, data:s.data, borderColor:i?PROG.series2:PROG.series1,
    backgroundColor:i?'rgba(245,162,0,.12)':PROG.series1Soft, borderWidth:2, tension:.3,
    fill:(i===0 && tr.series.length===1), pointRadius:3, pointHoverRadius:5, spanGaps:true }));
  progMake('prog-trend', { type:'line', data:{labels:tr.labels,datasets:ds},
    options:{responsive:true,maintainAspectRatio:false,
      plugins:{legend:{display:(tr.series||[]).length>1,labels:{color:PROG.ink,boxWidth:10,font:{size:10}}}},
      scales:PROG_AXES } });
}

function progSubjects(subs, lvl) {
  const labels = subs.map(s=>s.subject);
  const ds = [{ label:lvl==='student'?'Student':'Average', data:subs.map(s=>s.avg_score),
               backgroundColor:PROG.series1, borderRadius:4 }];
  if (lvl==='student' && subs.some(s=>s.class_avg!=null))
    ds.push({ label:'Class avg', data:subs.map(s=>s.class_avg), backgroundColor:PROG.series2, borderRadius:4 });
  progMake('prog-subjects', { type:'bar', data:{labels,datasets:ds},
    options:{responsive:true,maintainAspectRatio:false,
      plugins:{legend:{display:ds.length>1,labels:{color:PROG.ink,boxWidth:10,font:{size:10}}}},
      scales:{x:{grid:{display:false},ticks:{color:PROG.muted,font:{size:9},maxRotation:60,minRotation:30}},
              y:{beginAtZero:true,suggestedMax:100,grid:{color:PROG.grid},ticks:{color:PROG.muted,font:{size:10}}}} } });
}

function progTable(tbl, lvl) {
  if (!tbl || !tbl.rows.length) { $('prog-table').innerHTML = '<p class="tp-empty">No results.</p>'; return; }
  const numKeys = {avg_score:1,pass_rate:1,top_score:1,total_score:1,class_score:1,exam_score:1,students:0,results:0,subjects:0,position:0};
  const head = '<tr>' + tbl.columns.map(c=>`<th>${esc(c.label)}</th>`).join('') + '</tr>';
  const body = tbl.rows.map(r => '<tr>' + tbl.columns.map(c => {
    let v = r[c.key];
    if (c.key==='grade' && v) return `<td><span class="prog-grade" style="background:${PROG_GRADE[v]||'#666'}">${esc(v)}</span></td>`;
    if (c.key in numKeys) v = (v==null?'—':(+v).toFixed(numKeys[c.key]));
    else v = esc(v==null?'—':v);
    return `<td>${v}</td>`;
  }).join('') + '</tr>').join('');
  $('prog-table').innerHTML = `<table class="prog-tbl">${head}${body}</table>`;
}

// ── Init ───────────────────────────────────────────────────────
openTab(S.tab);
</script>

</body>
</html>
