<?= $this->extend('layouts/main') ?>
<?= $this->section('content') ?>
<?php
$dayNames   = ['','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'];
$activeDays = array_map('intval', explode(',', $schedule['active_days']));

// ── Palet warna guru (per teacher_id) ───────────────────────────
$teacherPalettes = []; // Kept for backward compatibility

function hslToHex($h, $s, $l) {
    $h /= 360;
    $s /= 100;
    $l /= 100;

    $r = $l;
    $g = $l;
    $b = $l;

    $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s);
    if ($v > 0) {
        $m = $l + $l - $v;
        $sv = ($v - $m) / $v;
        $h *= 6.0;
        $sextant = floor($h);
        $fract = $h - $sextant;
        $vsf = $v * $sv * $fract;
        $mid1 = $m + $vsf;
        $mid2 = $v - $vsf;

        switch ($sextant) {
            case 0: $r = $v; $g = $mid1; $b = $m; break;
            case 1: $r = $mid2; $g = $v; $b = $m; break;
            case 2: $r = $m; $g = $v; $b = $mid1; break;
            case 3: $r = $m; $g = $mid2; $b = $v; break;
            case 4: $r = $mid1; $g = $m; $b = $v; break;
            case 5: $r = $v; $g = $m; $b = $mid2; break;
        }
    }

    $r = (int)round($r * 255);
    $g = (int)round($g * 255);
    $b = (int)round($b * 255);

    return sprintf("#%02x%02x%02x", $r, $g, $b);
}

function getContrastColor($hex) {
    $hex = ltrim($hex, '#');
    if (strlen($hex) !== 6) return '#000000';
    $r = hexdec(substr($hex, 0, 2));
    $g = hexdec(substr($hex, 2, 2));
    $b = hexdec(substr($hex, 4, 2));
    $luminance = (0.299 * $r + 0.587 * $g + 0.114 * $b) / 255;
    return $luminance > 0.5 ? '#000000' : '#ffffff';
}

function teacherColor(int $tid, ?string $dbColor, array $p): array {
    if (!empty($dbColor) && strtolower($dbColor) !== '#cccccc') {
        return [
            'bg' => $dbColor,
            'text' => getContrastColor($dbColor),
            'border' => $dbColor
        ];
    }
    $hue = ($tid * 137.5) % 360;
    $sat = 70 + ($tid % 3) * 15;
    $lit = 40 + (($tid * 3) % 4) * 15;
    $bg = hslToHex($hue, $sat, $lit);
    $border = hslToHex($hue, $sat, max(25, $lit - 10));
    return [
        'bg' => $bg,
        'text' => getContrastColor($bg),
        'border' => $border
    ];
}

// ── Warna mapel (untuk per-kelas / per-guru) ─────────────────────
function subjectColor(int $sid): array {
    $p = [
        ['bg'=>'#EBF5FF','border'=>'#93C5FD','text'=>'#1E40AF'],
        ['bg'=>'#F0FDF4','border'=>'#86EFAC','text'=>'#166534'],
        ['bg'=>'#FDF4FF','border'=>'#E879F9','text'=>'#86198F'],
        ['bg'=>'#FFF7ED','border'=>'#FDB261','text'=>'#9A3412'],
        ['bg'=>'#F0F9FF','border'=>'#7DD3FC','text'=>'#0C4A6E'],
        ['bg'=>'#FFF1F2','border'=>'#FDA4AF','text'=>'#9F1239'],
        ['bg'=>'#F0FDFA','border'=>'#5EEAD4','text'=>'#134E4A'],
        ['bg'=>'#FEFCE8','border'=>'#FDE047','text'=>'#713F12'],
        ['bg'=>'#F5F3FF','border'=>'#C4B5FD','text'=>'#4C1D95'],
        ['bg'=>'#FFF8F1','border'=>'#FCA974','text'=>'#7C2D12'],
    ];
    return $p[$sid % count($p)];
}

// ── allTimeslotsMap[day][slot_number] = row ──────────────────────
$allTimeslotsMap = [];
foreach ($timeslots as $ts)
    $allTimeslotsMap[(int)$ts['day']][(int)$ts['slot_number']] = $ts;

$allSlotNumbers = [];
foreach ($allTimeslotsMap as $day => $slots)
    foreach ($slots as $num => $row) $allSlotNumbers[$num] = true;
ksort($allSlotNumbers);
$allSlotNumbers = array_keys($allSlotNumbers);

// ── Kelas & Guru unik ────────────────────────────────────────────
$classrooms = []; $teachers = []; $teacherMeta = []; $classroomGrades = [];
foreach ($gridData as $e) {
    $cid = (int)$e['classroom_id']; $tid = (int)$e['teacher_id'];
    if (!isset($classrooms[$cid])) {
        $classrooms[$cid] = $e['classroom_name'];
        $classroomGrades[$cid] = $e['grade_name'] ?? 'Lain';
    }
    if (!isset($teachers[$tid])) {
        $teachers[$tid] = $e['teacher_name'];
        $teacherMeta[$tid] = [
            'name'    => $e['teacher_name'],
            'nip'     => $e['teacher_nip']     ?? '','nip_label' => guess_id_label($e['teacher_nip'] ?? null),
            'user_id' => $e['teacher_user_id'] ?? '',
            'short_code' => $e['teacher_short_code'] ?? '',
            'color'   => $e['teacher_color']   ?? '',
        ];
    }
}
asort($classrooms); asort($teachers);

// Kelompokkan kelas per tingkat
$classroomGroups = [];
foreach ($classrooms as $cid => $cname) {
    $g = $classroomGrades[$cid] ?? 'Lain';
    $classroomGroups[$g][$cid] = $cname;
}
ksort($classroomGroups);

// ── Master grid [day][slot][cid][] = entry ─────────────────────────
$masterGrid = [];
foreach ($gridData as $e)
    $masterGrid[(int)$e['day']][(int)$e['slot_number']][(int)$e['classroom_id']][] = $e;

// ── Lock status per guru ─────────────────────────────────────────
$teacherLockStatus = [];
foreach ($teachers as $tid => $tname) {
    $totalEntries  = 0; $lockedEntries = 0;
    foreach ($gridData as $e) {
        if ((int)$e['teacher_id'] !== $tid) continue;
        $totalEntries++;
        if ((int)($e['is_locked'] ?? 0)) $lockedEntries++;
    }
    if ($totalEntries === 0)         $teacherLockStatus[$tid] = 'none';
    elseif ($lockedEntries === 0)    $teacherLockStatus[$tid] = 'none';
    elseif ($lockedEntries === $totalEntries) $teacherLockStatus[$tid] = 'all';
    else                             $teacherLockStatus[$tid] = 'partial';
}

// ── Subject colors untuk JS ──────────────────────────────────────
$subjColorsJs = [];
foreach ($gridData as $e) {
    $sid = (int)$e['school_subject_id'];
    if (!isset($subjColorsJs[$sid])) $subjColorsJs[$sid] = subjectColor($sid);
}
?>
<style>
/* ─── BASE ─── */
.grid-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}

/* ─── MODE TABS ─── */
.vmode-bar{display:flex;align-items:center;gap:2px;background:#f3f4f6;border-radius:8px;padding:3px;width:fit-content;margin-bottom:12px}
.vmode-btn{font-size:12px;padding:5px 14px;border-radius:6px;border:none;background:transparent;color:#6b7280;cursor:pointer;font-weight:500;transition:all .12s;white-space:nowrap}
.vmode-btn:hover{color:#111827;background:#e5e7eb}
.vmode-btn.active{background:#fff;color:#1d4ed8;font-weight:700;box-shadow:0 1px 3px rgba(0,0,0,.12)}

/* ─── ENTITY SELECTOR ─── */
.entity-selector{display:flex;align-items:center;gap:8px;margin-bottom:10px;flex-wrap:wrap}
.entity-selector label{font-size:12px;color:#6b7280;font-weight:600;white-space:nowrap}
.entity-select{border:1px solid #d1d5db;border-radius:7px;padding:5px 10px;font-size:13px;color:#111827;background:#fff;min-width:200px;max-width:340px;cursor:pointer;outline:none;transition:border-color .12s}
.entity-select:focus{border-color:#3b82f6;box-shadow:0 0 0 2px #dbeafe}
.nav-arrow{width:28px;height:28px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;color:#6b7280;font-size:14px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .12s;flex-shrink:0}
.nav-arrow:hover:not(:disabled){border-color:#3b82f6;color:#3b82f6;background:#EBF5FF}
.nav-arrow:disabled{opacity:.3;cursor:not-allowed}

/* ─── DETAIL TIMETABLE (Per Kelas & Per Guru) ─── */
.tt-table{border-collapse:separate;border-spacing:0;font-size:12px;width:100%}
.tt-table th{padding:7px 10px;font-size:11px;font-weight:700;color:#4b5563;background:#f9fafb;border-bottom:2px solid #e5e7eb;border-right:1px solid #f0f0f0;text-align:center;white-space:nowrap;position:sticky;top:0;z-index:2}
.tt-table th.col-slot{text-align:left;width:100px;min-width:100px;position:sticky;left:0;z-index:3;background:#f9fafb;border-right:2px solid #e5e7eb}
.tt-table td{border-right:1px solid #f0f0f0;border-bottom:1px solid #f0f0f0;padding:4px;vertical-align:top;min-width:115px;height:56px}
.tt-table td.col-slot{background:#fafafa;border-right:2px solid #e5e7eb;padding:4px 8px;position:sticky;left:0;z-index:1;vertical-align:middle}
.slot-num{font-weight:700;font-size:12px;color:#1f2937}
.slot-time{font-size:10px;color:#9ca3af;margin-top:1px}
.row-nonkbm td{background:#fffbeb!important;height:24px!important;padding:2px 8px!important;border-bottom:1px solid #fde68a!important}
.row-nonkbm td.col-slot{background:#fef3c7!important}
.row-nonkbm-label{font-size:10px;font-weight:600;color:#92400e}
.cell-nonkbm{background:#fffbeb!important;vertical-align:middle!important;padding:3px 5px!important}
.cell-nonkbm-label{font-size:10px;font-weight:600;color:#92400e}

/* entry card */
.ec{border-radius:5px;padding:4px 6px;height:100%;min-height:46px;border-left:3px solid;display:flex;flex-direction:column;justify-content:center;transition:filter .1s;position:relative}
.ec:hover{filter:brightness(.92)}
.ec-subj{font-weight:700;font-size:11px;line-height:1.2}
.ec-meta{font-size:10px;opacity:.68;margin-top:2px}
.ec.is-manual::after{position:absolute;top:2px;right:3px;content:'✎';opacity:.55;font-size:9px}

/* ─── MASTER TIMETABLE ─── */
.mt-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.mt-table{border-collapse:separate;border-spacing:0;font-size:11px}
.mt-table thead th{position:sticky;top:0;z-index:3}

/* Kolom HARI: sticky kiri, rowspan per hari */
.mt-col-day{
    background:#f0f4f8;border-right:2px solid #d1d5db;border-bottom:1px solid #e5e7eb;
    min-width:46px;width:46px;position:sticky;left:0;z-index:2;
    text-align:center;vertical-align:middle;padding:4px 2px;
}
.mt-table thead .mt-col-day{z-index:4;background:#e8edf2}
/* Teks hari vertikal */
.day-vert{
    writing-mode:vertical-rl;transform:rotate(180deg);
    font-size:11px;font-weight:700;color:#374151;
    white-space:nowrap;letter-spacing:.03em;
}

/* Kolom JAM: sticky kiri ke-2, di sebelah hari */
.mt-col-jam{
    background:#f9fafb;border-right:1px solid #e5e7eb;border-bottom:1px solid #e5e7eb;
    min-width:52px;width:52px;position:sticky;left:46px;z-index:2;
    text-align:center;vertical-align:middle;padding:3px 4px;
}
.mt-table thead .mt-col-jam{z-index:4;border-bottom:2px solid #e5e7eb}

/* Kolom JAM untuk non-KBM row: sangat tipis */
.mt-col-jam-nonkbm{
    background:#fffbeb;border-right:1px solid #fde68a;border-bottom:1px solid #fde68a;
    min-width:52px;width:52px;position:sticky;left:46px;z-index:2;
    padding:0;
}

/* Header kelas */
.mt-cls-th{background:#f9fafb;border-right:1px solid #e5e7eb;border-bottom:2px solid #e5e7eb;padding:5px 3px;font-size:10px;font-weight:700;color:#374151;text-align:center;white-space:nowrap;min-width:60px}

/* Sel data */
.mt-cell{border-right:1px solid #efefef;border-bottom:1px solid #efefef;padding:0 !important;vertical-align:middle;height:44px;min-width:60px}

/* Chip mapel */
.mt-chip{display:flex;flex-direction:column;align-items:center;justify-content:center;width:100%;height:100%;min-height:44px;border-radius:0;padding:4px 2px;font-size:10px;font-weight:700;line-height:1.2;text-align:center;overflow:hidden;transition:opacity .25s, filter .25s;word-break:break-word}
.mt-chip:hover{filter:brightness(.88)}
.mt-chip.is-locked{outline:2px solid #fbbf24}
.mt-chip.dimmed{opacity:.15 !important;filter:grayscale(100%) !important;pointer-events:none}
.mt-chip.highlighted{outline:2px solid #fff;outline-offset:-2px;z-index:1;position:relative}

/* Separator antar hari */
.mt-day-sep .mt-col-day,.mt-day-sep .mt-col-jam,.mt-day-sep .mt-col-jam-nonkbm,.mt-day-sep .mt-cell{border-top:2px solid #c8d0db!important}

/* Baris non-KBM: tipis, label colspan */
.mt-nonkbm-row .mt-cell{height:20px}
.mt-nonkbm-label-cell{
    background:#fffbeb;border-bottom:1px solid #fde68a;
    font-size:10px;font-weight:600;color:#92400e;
    padding:2px 8px;vertical-align:middle;
    border-right:1px solid #fde68a;
}

/* ─── LEGEND PANEL ─── */
.legend-panel{background:#fff;border:1px solid #e5e7eb;border-radius:10px;padding:10px 12px;margin-top:10px}
.legend-panel-title{font-size:11px;font-weight:700;color:#6b7280;text-transform:uppercase;letter-spacing:.04em;margin-bottom:8px}
.legend-grid{display:flex;flex-wrap:wrap;gap:5px}
.legend-item{
    display:flex;align-items:center;gap:5px;
    padding:4px 10px 4px 6px;border-radius:20px;
    border:1.5px solid transparent;
    cursor:pointer;transition:all .12s;
    font-size:11px;font-weight:600;
}
.legend-item:hover{filter:brightness(.93);transform:translateY(-1px)}
.legend-item.active-highlight{box-shadow:0 0 0 2px #111827}
.legend-item.is-locked-teacher{position:relative}
.legend-item.is-locked-teacher .legend-lock{display:inline}
.legend-lock{display:none;font-size:10px;margin-left:2px}
.legend-userid{font-size:9px;opacity:.65;font-weight:400;margin-left:2px}
.legend-sw{width:12px;height:12px;border-radius:3px;flex-shrink:0}

/* Lock action bar (muncul saat guru di-highlight) */
.lock-action-bar{
    display:none;
    align-items:center;gap:8px;
    background:#fff;border:1px solid #e5e7eb;border-radius:8px;
    padding:8px 12px;margin-top:8px;
    font-size:12px;
}
.lock-action-bar.visible{display:flex}
.lock-action-bar .teacher-info{flex:1}
.lock-action-bar .teacher-info strong{font-size:13px}
.lock-action-bar .teacher-info small{color:#6b7280}

/* Drag & Drop Styles */
.draggable {
    cursor: grab;
    user-select: none;
    transition: transform 0.1s;
}
.draggable:active {
    cursor: grabbing;
}
.dragging {
    opacity: 0.5;
    cursor: grabbing;
}
.drop-zone {
    transition: background 0.1s;
}
.drop-zone.drag-over {
    background: #c7e5ff !important;
    box-shadow: inset 0 0 0 2px #0d6efd;
}
.ec.locked-entry { cursor: not-allowed; opacity: 0.85; }
.mt-chip.locked-chip { cursor: not-allowed; }

/* ─── ASC MATRIX CLASSES ─── */
.schedule-matrix {
    table-layout: fixed;
    border-collapse: collapse;
    width: 100%;
}
.header-period-col {
    background: #1e3a5f;
    color: #fff;
    font-size: .75rem;
    padding: 6px 4px;
    min-width: 80px;
}
.header-day {
    background: #1e3a5f;
    color: #fff;
    padding: 5px 4px;
    min-width: 85px;
    font-size: .8rem;
}
.day-full {
    font-size: .65rem;
    opacity: .8;
    font-weight: normal;
}
.period-label {
    background: #f0f4f8;
    padding: 6px 4px;
}
.period-num {
    font-size: .9rem;
    font-weight: 700;
    line-height: 1.2;
}
.period-time {
    font-size: .65rem;
    color: #666;
    line-height: 1.2;
}
.schedule-cell {
    height: 65px;
    padding: 0 !important;
    transition: filter .15s;
}
.schedule-cell.has-slot:hover {
    filter: brightness(.88);
}
.empty-slot {
    background: #fafafa !important;
}
.slot-subject {
    font-size: .82rem;
    font-weight: 700;
    line-height: 1.2;
}
.slot-teacher {
    font-size: .7rem;
    line-height: 1.2;
    margin-top: 2px;
    opacity: .85;
}
.slot-class {
    font-size: .82rem;
    font-weight: 700;
    line-height: 1.2;
}

@media print{
    .no-print{display:none!important}
    .mt-table thead th,.mt-col-day,.mt-col-jam,.mt-col-jam-nonkbm,.tt-table th,.tt-table td.col-slot{position:static!important}
}

</style>

<!-- HEADER -->
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3 no-print">
    <div class="d-flex align-items-center gap-2">
        <a href="/schedule-generator/detail/<?= $schedule['id'] ?>" class="btn btn-sm btn-outline-secondary">
            <i class="bi bi-arrow-left"></i>
        </a>
        <div>
            <h5 class="mb-0 fw-semibold"><i class="bi bi-grid me-2 text-primary"></i><?= esc($schedule['name']) ?></h5>
            <small class="text-muted">
                <?= esc($schedule['year_name'] ?? '-') ?> &bull; <?= esc($schedule['period_name'] ?? '-') ?>
                &bull; <span class="text-primary fw-semibold"><?= count($classrooms) ?> kelas</span>
                &bull; <span class="text-success fw-semibold"><?= count($gridData) ?> jam terjadwal</span>
            </small>
        </div>
    </div>
    <button class="btn btn-outline-secondary btn-sm no-print" onclick="window.print()">
        <i class="bi bi-printer me-1"></i>Print
    </button>
</div>

<!-- MODE TABS -->
<div class="vmode-bar no-print">
    <button class="vmode-btn active" onclick="switchMode('master',this)"><i class="bi bi-table me-1"></i>Master Timetable</button>
    <button class="vmode-btn" onclick="switchMode('classroom',this)"><i class="bi bi-door-open me-1"></i>Per Kelas</button>
    <button class="vmode-btn" onclick="switchMode('teacher',this)"><i class="bi bi-person-badge me-1"></i>Per Guru</button>
</div>

<!-- ═══════════════════════════════════
     MASTER TIMETABLE
════════════════════════════════════ -->
<div id="modemaster">

    <!-- ① LEGEND GURU — di atas -->
    <div class="legend-panel no-print mb-2">
        <div class="d-flex align-items-center justify-content-between mb-2">
            <div class="legend-panel-title mb-0">
                <i class="bi bi-palette me-1"></i>Kode Guru — Klik untuk highlight &amp; lock
            </div>
        </div>
        <div class="legend-grid" id="teacherLegend">
            <?php foreach ($teachers as $tid => $tname):
                $meta   = $teacherMeta[$tid];
                $tc     = teacherColor((int)$tid, $meta['color'], $teacherPalettes);
                $status = $teacherLockStatus[$tid];
                $uid    = $meta['user_id'] ?: '-';
            ?>
            <div class="legend-item <?= $status==='all'?'is-locked-teacher':'' ?>"
                 style="background:<?= $tc['bg'] ?>;color:<?= $tc['text'] ?>;border-color:<?= $tc['border'] ?>"
                 data-teacher-id="<?= $tid ?>"
                 data-lock-status="<?= $status ?>"
                 onclick="highlightTeacher(<?= $tid ?>, this)"
                 title="<?= esc($tname) ?> | User ID: <?= esc($uid) ?>">
                <span class="legend-sw" style="background:<?= $tc['text'] ?>22;outline:1px solid <?= $tc['border'] ?>"></span>
                <span><?= esc(mb_substr($tname,0,22,'UTF-8')) ?></span>
                <span class="legend-userid">[<?= esc($uid) ?>]</span>
                <span class="legend-lock">🔒</span>
            </div>
            <?php endforeach; ?>
        </div>
    </div>

    <!-- ② LOCK ACTION BAR — muncul setelah klik guru di legend -->
    <div class="lock-action-bar no-print mb-2" id="lockActionBar">
        <div class="teacher-info">
            <div><strong id="lockBarName">—</strong>
                <span class="ms-2 badge rounded-pill" id="lockBarBadge" style="font-size:10px"></span>
            </div>
            <small id="lockBarSub" class="text-muted"></small>
        </div>
        <button class="btn btn-sm btn-warning" onclick="lockTeacherAction('lock')">
            <i class="bi bi-lock-fill me-1"></i>Kunci Semua Jadwal Guru Ini
        </button>
        <button class="btn btn-sm btn-outline-secondary" onclick="lockTeacherAction('unlock')">
            <i class="bi bi-unlock me-1"></i>Buka Kunci
        </button>
        <button class="btn btn-sm btn-outline-light border" onclick="clearHighlight()" title="Tutup">
            <i class="bi bi-x"></i>
        </button>
    </div>

    <!-- ③ TABEL — Hari di-rowspan, Jam kolom kedua -->
    <div class="card border-0 shadow-sm">
        <div class="card-body p-0">
            <div class="mt-wrap">
                <table class="mt-table" id="masterTable">
                    <thead>
                        <tr>
                            <th class="mt-col-day" rowspan="1" style="background:#f3f4f6;font-size:10px;color:#9ca3af;padding:4px;text-align:center">Hari</th>
                            <th class="mt-col-jam"  style="background:#f9fafb;font-size:10px;color:#9ca3af;padding:4px;text-align:center">Jam</th>
                            <?php foreach ($classrooms as $cid => $cname): ?>
                            <th class="mt-cls-th"><?= esc($cname) ?></th>
                            <?php endforeach; ?>
                        </tr>
                    </thead>
                    <tbody>
                    <?php
                    // Pre-compute: per hari, hitung jumlah baris (KBM + non-KBM yang ada)
                    $dayRowCount = [];
                    foreach ($activeDays as $dayNum) {
                        $cnt = 0;
                        foreach ($allSlotNumbers as $slotNum) {
                            if (isset($allTimeslotsMap[$dayNum][$slotNum])) $cnt++;
                        }
                        $dayRowCount[$dayNum] = $cnt;
                    }

                    $prevDay       = null;

                    foreach ($activeDays as $dayNum):
                        foreach ($allSlotNumbers as $slotNum):
                            $slotRow = $allTimeslotsMap[$dayNum][$slotNum] ?? null;
                            if (!$slotRow) continue;

                            $isKbm    = ($slotRow['slot_type'] === 'kbm');
                            $isNewDay = ($prevDay !== $dayNum);
                            $prevDay  = $dayNum;
                            $rowspan  = $dayRowCount[$dayNum];
                            $totalCls = count($classrooms);
                    ?>
                    <?php if ($isKbm): ?>
                    <tr class="<?= $isNewDay ? 'mt-day-sep' : '' ?>">
                        <?php if ($isNewDay): ?>
                        <td class="mt-col-day" rowspan="<?= $rowspan ?>">
                            <div class="day-vert"><?= $dayNames[$dayNum] ?></div>
                        </td>
                        <?php endif; ?>
                        <td class="mt-col-jam">
                            <div style="font-weight:700;font-size:11px;color:#1f2937;line-height:1.2"><?= esc($slotRow['label']) ?></div>
                            <div style="font-size:9px;color:#9ca3af"><?= substr($slotRow['start_time'],0,5) ?>–<?= substr($slotRow['end_time'],0,5) ?></div>
                        </td>
                        <?php foreach ($classrooms as $cid => $cname):
                            $cellEntries = $masterGrid[$dayNum][$slotNum][$cid] ?? [];
                            $isClash = count($cellEntries) > 1;
                        ?>
                        <td class="mt-cell <?= $isClash ? 'table-danger' : '' ?>">
                        <?php foreach ($cellEntries as $entry):
                            $tc = teacherColor((int)$entry['teacher_id'], $entry['teacher_color'], $teacherPalettes);
                            $code = esc($entry['subject_code'] ?: mb_substr($entry['subject_name'],0,7,'UTF-8'));
                            $teacherCodeDisplay = esc($entry['teacher_short_code'] ?: ($entry['teacher_user_id'] ?: mb_substr($entry['teacher_name'], 0, 10)));
                            $isLocked = (int)($entry['is_locked'] ?? 0);
                        ?>
                            <div class="mt-chip <?= $isLocked ? 'is-locked' : '' ?>"
                                 style="background:<?= $tc['bg'] ?>;color:<?= $tc['text'] ?>;border-color:<?= $isClash ? '#ef4444' : $tc['border'] ?>; <?= $isClash ? 'border-width:2px; font-weight:bold;' : '' ?>"
                                 title="<?= esc($entry['subject_name']) ?> — <?= esc($entry['teacher_name']) ?>"
                                 data-teacher-id="<?= $entry['teacher_id'] ?>">
                                <div class="fw-bold lh-1" style="font-size:.78rem"><?= $code ?></div>
                                <div class="lh-1 mt-1" style="font-size:.68rem;opacity:.85">[<?= $teacherCodeDisplay ?>]</div>
                            </div>
                        <?php endforeach; ?>
                        </td>
                        <?php endforeach; ?>
                    </tr>

                    <?php else: // ── NON-KBM: baris tipis, label colspan semua kolom kelas ?>
                    <tr class="mt-nonkbm-row <?= $isNewDay ? 'mt-day-sep' : '' ?>">
                        <?php if ($isNewDay): ?>
                        <td class="mt-col-day" rowspan="<?= $rowspan ?>">
                            <div class="day-vert"><?= $dayNames[$dayNum] ?></div>
                        </td>
                        <?php endif; ?>
                        <td class="mt-col-jam-nonkbm"></td>
                        <td class="mt-nonkbm-label-cell" colspan="<?= $totalCls ?>">
                            <?php
                            $icon = match($slotRow['slot_type']) {
                                'istirahat'  => '☕',
                                'upacara'    => '🚩',
                                'keagamaan'  => '🌙',
                                default      => '•',
                            };
                            ?>
                            <?= $icon ?> <?= esc($slotRow['label']) ?>
                        </td>
                    </tr>
                    <?php endif; ?>
                    <?php endforeach; endforeach; ?>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
</div>

<!-- ═══════════════════════════════════
     PER KELAS
════════════════════════════════════ -->
<div id="modeclassroom" style="display:none">
    <div class="entity-selector no-print">
        <button class="nav-arrow" id="clsPrev" onclick="navEntity('cls',-1)">&#8249;</button>
        <label for="selClassroom"><i class="bi bi-door-open me-1"></i>Kelas:</label>
        <select class="entity-select" id="selClassroom" onchange="renderClassroom(this.value)">
            <?php foreach ($classroomGroups as $grade => $clsMap): ?>
            <optgroup label="Tingkat <?= esc($grade) ?>">
                <?php foreach ($clsMap as $cid => $cname): ?>
                <option value="<?= $cid ?>"><?= esc($cname) ?></option>
                <?php endforeach; ?>
            </optgroup>
            <?php endforeach; ?>
        </select>
        <button class="nav-arrow" id="clsNext" onclick="navEntity('cls',1)">&#8250;</button>
        <small class="text-muted" id="clsCounter" style="font-size:11px"></small>
    </div>
    <div class="card border-0 shadow-sm">
        <div class="card-header bg-white border-0 pt-2 pb-1 px-3 no-print">
            <span class="fw-semibold text-primary" id="clsTitle" style="font-size:13px"></span>
        </div>
        <div class="card-body p-0" id="gridClassroom"></div>
    </div>
</div>

<!-- ═══════════════════════════════════
     PER GURU
════════════════════════════════════ -->
<div id="modeteacher" style="display:none">
    <div class="entity-selector no-print">
        <button class="nav-arrow" id="tchPrev" onclick="navEntity('tch',-1)">&#8249;</button>
        <label for="selTeacher"><i class="bi bi-person-badge me-1"></i>Guru:</label>
        <select class="entity-select" id="selTeacher" onchange="renderTeacher(this.value)">
            <?php foreach ($teachers as $tid => $tname):
                $meta   = $teacherMeta[$tid];
                $uid    = $meta['user_id'] ?: '-';
                $status = $teacherLockStatus[$tid];
                $lockIcon = $status === 'all' ? ' 🔒' : ($status === 'partial' ? ' 🔓' : '');
            ?>
            <option value="<?= $tid ?>"><?= esc($tname) ?> [<?= esc($uid) ?>]<?= $lockIcon ?></option>
            <?php endforeach; ?>
        </select>
        <button class="nav-arrow" id="tchNext" onclick="navEntity('tch',1)">&#8250;</button>
        <small class="text-muted" id="tchCounter" style="font-size:11px"></small>
    </div>
    <div class="card border-0 shadow-sm">
        <div class="card-header bg-white border-0 pt-2 pb-1 px-3 no-print d-flex align-items-center justify-content-between">
            <span class="fw-semibold text-primary" id="tchTitle" style="font-size:13px"></span>
            <div class="d-flex gap-2" id="tchLockButtons">
                <button class="btn btn-sm btn-warning" onclick="lockCurrentTeacher('lock')">
                    <i class="bi bi-lock-fill me-1"></i>Kunci Semua
                </button>
                <button class="btn btn-sm btn-outline-secondary" onclick="lockCurrentTeacher('unlock')">
                    <i class="bi bi-unlock me-1"></i>Buka Kunci
                </button>
            </div>
        </div>
        <div class="card-body p-0" id="gridTeacher"></div>
    </div>
</div>

<!-- Detail legend -->
<div id="detailLegend" style="display:none" class="mt-2 no-print">
    <small class="text-muted">
        <span style="background:#fffbeb;border:1px solid #fde68a;padding:1px 6px;border-radius:3px;color:#92400e;font-size:10px">✎</span> diedit manual &nbsp;
        <span class="text-muted" style="font-size:11px">• Klik guru di legend untuk lock/unlock semua jadwal</span>
    </small>
</div>

<!-- Toast -->
<!-- Print-only Legend Mapping Teacher Short Codes to Names -->
<div class="d-none d-print-block mt-4 pt-3 border-top page-break-inside-avoid">
    <h6 class="fw-bold mb-2">Daftar Singkatan Nama Guru (Legenda):</h6>
    <div class="d-flex flex-wrap gap-x-4 gap-y-1" style="font-size: 10px; line-height: 1.4;">
        <?php 
        $printLegendItems = [];
        foreach ($teacherMeta as $tid => $meta) {
            $code = $meta['short_code'] ?: ($meta['user_id'] ?: substr($meta['name'], 0, 10));
            $printLegendItems[] = '<span class="fw-bold">' . esc($code) . '</span>: ' . esc($meta['name']);
        }
        echo implode(' &bull; ', $printLegendItems);
        ?>
    </div>
</div>

<div id="toast" style="position:fixed;bottom:20px;right:20px;z-index:9999;padding:9px 16px;border-radius:8px;font-size:12px;display:none;box-shadow:0 4px 12px rgba(0,0,0,.25);color:#fff"></div>

<?= $this->endSection() ?>
<?= $this->section('scripts') ?>
<script>
function getContrastColor(hex) {
    if (!hex) return '#000000';
    hex = hex.replace('#', '');
    if (hex.length !== 6) return '#000000';
    const r = parseInt(hex.substring(0, 2), 16);
    const g = parseInt(hex.substring(2, 4), 16);
    const b = parseInt(hex.substring(4, 6), 16);
    const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
    return luminance > 0.5 ? '#000000' : '#ffffff';
}

function hslToHex(h, s, l) {
    l /= 100;
    const a = s * Math.min(l, 1 - l) / 100;
    const f = n => {
        const k = (n + h / 30) % 12;
        const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
        return Math.round(255 * color).toString(16).padStart(2, '0');
    };
    return `#${f(0)}${f(8)}${f(4)}`;
}

function getTeacherColor(teacherId, dbColor) {
    if (dbColor && dbColor.toLowerCase() !== '#cccccc') {
        return {
            bg: dbColor,
            text: getContrastColor(dbColor),
            border: dbColor
        };
    }
    const hue = (teacherId * 137.5) % 360;
    const sat = 70 + (teacherId % 3) * 15;
    const lit = 40 + ((teacherId * 3) % 4) * 15;
    const bg = hslToHex(hue, sat, lit);
    const border = hslToHex(hue, sat, Math.max(25, lit - 10));
    return {
        bg: bg,
        text: getContrastColor(bg),
        border: border
    };
}

const SCHEDULE_ID = <?= $schedule['id'] ?>;
const CSRF_TOKEN  = document.querySelector('meta[name="csrf-token"]')?.content || '';

const ACTIVE_DAYS      = <?= json_encode($activeDays) ?>;
const DAY_NAMES        = <?= json_encode($dayNames) ?>;
const ALL_SLOT_NUMBERS = <?= json_encode($allSlotNumbers) ?>;
const ALL_TIMESLOTS    = <?= json_encode($allTimeslotsMap) ?>;
const GRID_CLS         = <?= json_encode($gridByClassroom) ?>;
const GRID_TCH         = <?= json_encode($gridByTeacher) ?>;
const SUBJ_COLORS      = <?= json_encode($subjColorsJs) ?>;
const TEACHER_PALETTES = <?= json_encode($teacherPalettes) ?>;

const CLASSROOMS = <?= json_encode(array_map(fn($id,$n)=>['id'=>$id,'name'=>$n], array_keys($classrooms), array_values($classrooms))) ?>;
const TEACHERS   = <?= json_encode(array_map(fn($id,$n)=>['id'=>$id,'name'=>$n], array_keys($teachers),   array_values($teachers))) ?>;
const TEACHER_META = <?= json_encode($teacherMeta) ?>;

let activeHighlightTeacherId = null;
const TEACHER_LOCK_STATUS = <?= json_encode($teacherLockStatus) ?>;

// ==================== MODE SWITCH ====================
function switchMode(mode, btn) {
    document.querySelectorAll('.vmode-btn').forEach(b => b.classList.remove('active'));
    btn.classList.add('active');
    ['modemaster','modeclassroom','modeteacher'].forEach(m =>
        document.getElementById(m).style.display = 'none');
    document.getElementById('mode'+mode).style.display = '';
    document.getElementById('detailLegend').style.display = mode !== 'master' ? '' : 'none';
    if (mode === 'classroom') renderClassroom(document.getElementById('selClassroom').value);
    if (mode === 'teacher')   renderTeacher(document.getElementById('selTeacher').value);
}

// ==================== NAV ARROWS ====================
function navEntity(type, dir) {
    const sel  = document.getElementById(type==='cls' ? 'selClassroom' : 'selTeacher');
    const opts = Array.from(sel.options).filter(o => !o.disabled && o.value !== '');
    const idx  = opts.findIndex(o => o.selected);
    const next = idx + dir;
    if (next < 0 || next >= opts.length) return;
    opts[next].selected = true;
    sel.dispatchEvent(new Event('change'));
}
function updateCounter(type) {
    const sel   = document.getElementById(type==='cls' ? 'selClassroom' : 'selTeacher');
    const opts  = Array.from(sel.options).filter(o => !o.disabled && o.value !== '');
    const idx   = opts.findIndex(o => o.selected);
    document.getElementById(type==='cls' ? 'clsCounter' : 'tchCounter').textContent = `${idx+1} / ${opts.length}`;
    document.getElementById(type==='cls' ? 'clsPrev' : 'tchPrev').disabled = idx <= 0;
    document.getElementById(type==='cls' ? 'clsNext' : 'tchNext').disabled = idx >= opts.length-1;
}

// ==================== HIGHLIGHT GURU ====================
function highlightTeacher(tid, legendEl) {
    const targets = document.querySelectorAll('#masterTable .mt-chip, #gridClassroom .ec, #gridTeacher .ec');

    if (activeHighlightTeacherId === tid) {
        clearHighlight();
        return;
    }

    activeHighlightTeacherId = tid;
    targets.forEach(chip => {
        const ctid = chip.dataset.teacherId;
        chip.classList.toggle('dimmed',      ctid != tid);
        chip.classList.toggle('highlighted', ctid == tid);
    });

    document.querySelectorAll('.legend-item').forEach(el => el.classList.remove('active-highlight'));
    legendEl.classList.add('active-highlight');

    const meta = TEACHER_META[tid] || {};
    const status = TEACHER_LOCK_STATUS[tid] || 'none';
    const uid = meta.user_id || '-';
    document.getElementById('lockBarName').textContent = meta.name || '?';
    document.getElementById('lockBarSub').textContent = `User ID: ${uid} | ${meta.nip_label||'NIP'}: ${meta.nip||'-'}`;
    document.getElementById('lockBarBadge').textContent = status === 'all' ? '🔒 Semua Terkunci' : (status === 'partial' ? '🔓 Sebagian' : 'Belum Terkunci');
    document.getElementById('lockBarBadge').className = 'ms-2 badge rounded-pill ' + (status === 'all' ? 'bg-warning text-dark' : status === 'partial' ? 'bg-secondary' : 'bg-light text-dark');
    document.getElementById('lockActionBar').classList.add('visible');
    document.getElementById('lockActionBar').dataset.teacherId = tid;
}

function clearHighlight() {
    activeHighlightTeacherId = null;
    document.querySelectorAll('#masterTable .mt-chip, #gridClassroom .ec, #gridTeacher .ec').forEach(c => {
        c.classList.remove('dimmed','highlighted');
    });
    document.querySelectorAll('.legend-item').forEach(el => el.classList.remove('active-highlight'));
    document.getElementById('lockActionBar').classList.remove('visible');
}

// ==================== LOCK PER GURU ====================
function lockTeacherAction(action) {
    const bar = document.getElementById('lockActionBar');
    const tid = bar.dataset.teacherId;
    if (!tid) return;
    _doLockTeacher(parseInt(tid), action, () => {
        document.querySelectorAll(`#masterTable .mt-chip[data-teacher-id="${tid}"]`).forEach(chip => {
            if (action === 'lock') chip.classList.add('is-locked');
            else chip.classList.remove('is-locked');
        });
        const legendEl = document.querySelector(`.legend-item[data-teacher-id="${tid}"]`);
        if (legendEl) {
            legendEl.classList.toggle('is-locked-teacher', action === 'lock');
            legendEl.dataset.lockStatus = action === 'lock' ? 'all' : 'none';
        }
        TEACHER_LOCK_STATUS[tid] = action === 'lock' ? 'all' : 'none';
        const meta = TEACHER_META[tid] || {};
        const status = TEACHER_LOCK_STATUS[tid];
        document.getElementById('lockBarBadge').textContent = status === 'all' ? '🔒 Semua Terkunci' : 'Belum Terkunci';
        showToast(action === 'lock' ? `🔒 Jadwal ${meta.name} dikunci` : `🔓 Jadwal ${meta.name} dibuka`);
    });
}

let currentTeacherId = null;
function lockCurrentTeacher(action) {
    if (!currentTeacherId) return;
    _doLockTeacher(currentTeacherId, action, () => {
        TEACHER_LOCK_STATUS[currentTeacherId] = action === 'lock' ? 'all' : 'none';
        const meta = TEACHER_META[currentTeacherId] || {};
        showToast(action === 'lock' ? `🔒 Jadwal ${meta.name} dikunci` : `🔓 Jadwal ${meta.name} dibuka`);
        renderTeacher(currentTeacherId);
    });
}

function _doLockTeacher(tid, action, onSuccess) {
    fetch(`/schedule-generator/lock-teacher/${SCHEDULE_ID}/${tid}/${action}`, {
        method: 'POST',
        headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': CSRF_TOKEN }
    })
    .then(r => r.json())
    .then(d => { if (d.success) onSuccess(); else showToast('Gagal: ' + d.message, true); })
    .catch(() => showToast('Gagal menghubungi server', true));
}

// ==================== RENDER GRID (Per Kelas & Per Guru) ====================
function renderGrid(entityId, gridData, metaKey, titleEl, containerEl, counterType) {
    const list   = counterType === 'cls' ? CLASSROOMS : TEACHERS;
    const entity = list.find(e => e.id == entityId);
    titleEl.textContent = entity?.name || '';
    if (counterType === 'tch') currentTeacherId = parseInt(entityId);
    updateCounter(counterType);

    // Kumpulkan semua slot per hari
    const allSlotsPerDay = {};
    ACTIVE_DAYS.forEach(day => {
        allSlotsPerDay[day] = [];
        ALL_SLOT_NUMBERS.forEach(slotNum => {
            const ts = ALL_TIMESLOTS[day]?.[slotNum];
            if (ts) {
                allSlotsPerDay[day].push({
                    slot_number: slotNum,
                    slot_type: ts.slot_type,
                    label: ts.label,
                    start_time: ts.start_time,
                    end_time: ts.end_time
                });
            }
        });
        allSlotsPerDay[day].sort((a,b) => a.slot_number - b.slot_number);
    });

    // Cari semua slot number unik
    const allUniqueSlots = [];
    const slotMap = {};
    ACTIVE_DAYS.forEach(day => {
        allSlotsPerDay[day].forEach(slot => {
            if (!slotMap[slot.slot_number]) {
                slotMap[slot.slot_number] = slot;
                allUniqueSlots.push(slot);
            }
        });
    });
    allUniqueSlots.sort((a,b) => a.slot_number - b.slot_number);

    let html = '<div class="grid-wrap"><table class="table table-bordered mb-0 schedule-matrix" id="' + (counterType === 'cls' ? 'classGrid' : 'teacherGrid') + '"><thead><tr>';
    html += '<th class="text-center align-middle header-period-col">Jam</th>';
    ACTIVE_DAYS.forEach(d => {
        const dName = DAY_NAMES[d] || '';
        const shortName = dName.substring(0, 3).toUpperCase();
        html += `<th class="text-center align-middle header-day">
            ${shortName}
            <div class="day-full small fw-normal">${dName}</div>
        </th>`;
    });
    html += '</tr></thead><tbody>';

    allUniqueSlots.forEach(slotInfo => {
        const slotNum = slotInfo.slot_number;
        const startStr = slotInfo.start_time ? slotInfo.start_time.substring(0, 5) : '';
        const endStr = slotInfo.end_time ? slotInfo.end_time.substring(0, 5) : '';
        
        let allNonKbm = true;
        let anyKbm = false;
        ACTIVE_DAYS.forEach(day => {
            const daySlot = allSlotsPerDay[day].find(s => s.slot_number === slotNum);
            if (daySlot && daySlot.slot_type === 'kbm') {
                allNonKbm = false;
                anyKbm = true;
            }
        });

        // Jika semua hari non-KBM
        if (allNonKbm && anyKbm === false) {
            const firstDaySlot = allSlotsPerDay[ACTIVE_DAYS[0]]?.find(s => s.slot_number === slotNum);
            const icon = firstDaySlot?.slot_type === 'istirahat' ? '☕' : 
                        (firstDaySlot?.slot_type === 'upacara' ? '🚩' : 
                        (firstDaySlot?.slot_type === 'keagamaan' ? '🌙' : '•'));
            html += `<tr class="row-nonkbm"><td class="text-center align-middle period-label"><div class="period-num">${slotNum}</div></td>`;
            ACTIVE_DAYS.forEach(day => {
                const daySlot = allSlotsPerDay[day].find(s => s.slot_number === slotNum);
                const label = daySlot ? daySlot.label : (firstDaySlot ? firstDaySlot.label : 'Istirahat');
                html += `<td class="cell-nonkbm text-center align-middle" style="background:#fffbeb !important;"><span class="cell-nonkbm-label" style="font-size:10px; font-weight:600; color:#92400e;">${icon} ${esc(label)}</span></td>`;
            });
            html += '</tr>';
            return;
        }

        html += `<tr><td class="text-center align-middle period-label">
            <div class="period-num">${slotNum}</div>
            <div class="period-time">${startStr}–${endStr}</div>
        </td>`;

        ACTIVE_DAYS.forEach(day => {
            const daySlot = allSlotsPerDay[day].find(s => s.slot_number === slotNum);
            
            if (!daySlot) {
                html += '<td class="empty-slot" style="background:#fafafa !important"></td>';
                return;
            }
            
            if (daySlot.slot_type !== 'kbm') {
                const icon = daySlot.slot_type === 'istirahat' ? '☕' : 
                            (daySlot.slot_type === 'upacara' ? '🚩' : 
                            (daySlot.slot_type === 'keagamaan' ? '🌙' : '•'));
                html += `<td class="cell-nonkbm text-center align-middle" style="background:#fffbeb !important;"><span class="cell-nonkbm-label" style="font-size:10px; font-weight:600; color:#92400e;">${icon} ${esc(daySlot.label)}</span></td>`;
                return;
            }
            
            const entries = gridData[entityId]?.[day]?.[slotNum] || [];
            
            if (entries.length === 0) {
                html += `<td class="drop-zone empty-slot" data-day="${day}" data-slot="${slotNum}" style="background:#fafafa !important"></td>`;
                return;
            }

            const isClash = entries.length > 1;
            let cellHtml = '';
            
            entries.forEach(entry => {
                const tc = getTeacherColor(entry.teacher_id, entry.teacher_color);
                const isManual = +entry.is_manual || 0;
                const isLocked = +entry.is_locked || 0;
                let cls = isManual ? 'is-manual' : '';
                if (isLocked) cls += ' locked-entry';
                const code = esc(entry.subject_code || (entry.subject_name || '').substring(0,8));
                let displayMeta = entry[metaKey];
                if (metaKey === 'teacher_name') {
                    displayMeta = entry.teacher_short_code || entry.teacher_user_id || (entry.teacher_name ? entry.teacher_name.substring(0, 10) : '');
                }
                const displayMetaEsc = esc(displayMeta || '');
                const entryId = entry.id || '';
                const subjName = esc(entry.subject_name || '');
                const teachName = esc(entry.teacher_name || '');

                const lockIcon = isLocked
                    ? `<i class="bi bi-lock-fill" style="position:absolute;top:2px;right:3px;font-size:9px;opacity:0.6"></i>`
                    : '';

                let dimmedClass = '';
                let highlightedClass = '';
                if (activeHighlightTeacherId !== null) {
                    if (parseInt(entry.teacher_id) === activeHighlightTeacherId) {
                        highlightedClass = ' highlighted';
                    } else {
                        dimmedClass = ' dimmed';
                    }
                }

                const itemStyle = isClash
                    ? `background:${tc.bg}; color:${tc.text}; border: 1px solid #ef4444; margin: 2px; padding: 2px 4px; border-radius: 4px; font-size: 10px; position: relative; display: block;`
                    : `width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; min-height: 65px; border: none; border-radius: 0; padding: 4px 2px; position: relative;`;

                cellHtml += `<div class="ec draggable ${cls}${dimmedClass}${highlightedClass}"
                            data-entry-id="${entryId}"
                            data-day="${day}"
                            data-slot="${slotNum}"
                            data-subject-name="${subjName}"
                            data-teacher-name="${teachName}"
                            data-teacher-id="${entry.teacher_id}"
                            title="${subjName} — ${teachName}"
                            style="${itemStyle}">
                            ${lockIcon}
                            <div class="${counterType === 'cls' ? 'slot-subject' : 'slot-class'}">${counterType === 'cls' ? code : displayMetaEsc}</div>
                            <div class="${counterType === 'cls' ? 'slot-teacher' : 'slot-subject'}">${counterType === 'cls' ? '[' + displayMetaEsc + ']' : code}</div>
                        </div>`;
            });

            const firstTc = getTeacherColor(entries[0].teacher_id, entries[0].teacher_color);
            const tdBgStyle = isClash ? '' : `background:${firstTc.bg}; color:${firstTc.text};`;
            html += `<td class="text-center align-middle schedule-cell drop-zone has-slot ${isClash ? 'table-danger' : ''}" data-day="${day}" data-slot="${slotNum}" style="${tdBgStyle} padding: 0 !important; cursor: default;">`;
            html += cellHtml;
            html += '</td>';
        });
        html += '</tr>';
    });

    html += '</tbody></table></div>';
    containerEl.innerHTML = html;
}

function renderClassroom(id) {
    if (!id) return;
    renderGrid(id, GRID_CLS, 'teacher_name', document.getElementById('clsTitle'), document.getElementById('gridClassroom'), 'cls');
    setTimeout(() => initDragDrop(), 50);
}
function renderTeacher(id) {
    if (!id) return;
    renderGrid(id, GRID_TCH, 'classroom_name', document.getElementById('tchTitle'), document.getElementById('gridTeacher'), 'tch');
    setTimeout(() => initDragDrop(), 50);
}

// ==================== TOAST ====================
function showToast(msg, err=false) {
    const t = document.getElementById('toast');
    t.textContent = msg;
    t.style.background = err ? '#dc2626' : '#1f2937';
    t.style.display = 'block';
    clearTimeout(t._t);
    t._t = setTimeout(() => { t.style.display = 'none'; }, 2800);
}
function esc(s) {
    return String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}

// ═══════════════════════════════════════════════════════════════
// DRAG & DROP — Grid Per Kelas dan Per Guru
// ═══════════════════════════════════════════════════════════════

let _dragEntryId   = null;
let _dragOldDay    = null;
let _dragOldSlot   = null;
let _dragSubjName  = null;
let _dragTeachName = null;

function initDragDrop() {
    // Tambahkan draggable pada semua entry card yang tidak locked
    document.querySelectorAll('.ec:not(.locked-entry)').forEach(cell => {
        const entryId = cell.dataset.entryId;
        if (!entryId) return;
        if (cell.getAttribute('draggable') === 'true') return; // sudah diinit

        cell.setAttribute('draggable', 'true');
        cell.classList.add('draggable');

        cell.addEventListener('dragstart', function(e) {
            _dragEntryId   = this.dataset.entryId;
            _dragOldDay    = this.dataset.day;
            _dragOldSlot   = this.dataset.slot;
            _dragSubjName  = this.dataset.subjectName || '—';
            _dragTeachName = this.dataset.teacherName || '—';
            this.classList.add('dragging');
            e.dataTransfer.effectAllowed = 'move';
            e.dataTransfer.setData('text/plain', _dragEntryId);
        });

        cell.addEventListener('dragend', function() {
            this.classList.remove('dragging');
        });
    });

    // Tambahkan drop zone pada semua td.drop-zone
    document.querySelectorAll('td.drop-zone').forEach(td => {
        if (td.dataset.ddInit) return; // sudah diinit
        td.dataset.ddInit = '1';

        td.addEventListener('dragover', function(e) {
            if (!_dragEntryId) return;
            e.preventDefault();
            this.classList.add('drag-over');
        });

        td.addEventListener('dragleave', function() {
            this.classList.remove('drag-over');
        });

        td.addEventListener('drop', function(e) {
            e.preventDefault();
            this.classList.remove('drag-over');
            const newDay  = parseInt(this.dataset.day);
            const newSlot = parseInt(this.dataset.slot);
            if (!_dragEntryId || !newDay || !newSlot) return;
            confirmMoveEntry(_dragEntryId, newDay, newSlot, _dragSubjName, _dragTeachName);
        });
    });
}

async function confirmMoveEntry(entryId, newDay, newSlot, subjName, teachName) {
    const dayNamesLocal = ['','Senin','Selasa','Rabu','Kamis','Jumat','Sabtu'];
    const confirmed = await Swal.fire({
        title: 'Pindah Jadwal?',
        html: `<div style="font-size:13px;text-align:left">
            <strong>${subjName}</strong> (${teachName})<br>
            akan dipindah ke <strong>${dayNamesLocal[newDay] || 'Hari ' + newDay} slot ${newSlot}</strong>
        </div>`,
        icon: 'question',
        showCancelButton: true,
        confirmButtonText: 'Ya, Pindahkan',
        cancelButtonText: 'Batal',
        confirmButtonColor: '#4f46e5',
    });
    if (!confirmed.isConfirmed) return;

    try {
        const res  = await fetch(`/schedule-generator/move-entry/${SCHEDULE_ID}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-Requested-With': 'XMLHttpRequest',
                'X-CSRF-TOKEN': CSRF_TOKEN,
            },
            body: JSON.stringify({
                entry_id:    parseInt(entryId),
                target_day:  newDay,
                target_slot: newSlot,
            }),
        });
        const data = await res.json();

        if (data.success) {
            showToast(data.message || 'Entry berhasil dipindah');
            setTimeout(() => location.reload(), 800);
        } else {
            Swal.fire({
                icon: 'error',
                title: 'Tidak Bisa Dipindahkan',
                html: data.message || 'Terjadi konflik.',
                confirmButtonText: 'Mengerti',
            });
        }
    } catch (ex) {
        Swal.fire({ icon: 'error', title: 'Error!', text: ex.message });
    }
}

// ==================== INIT ====================
document.addEventListener('DOMContentLoaded', () => {
    const selCls = document.getElementById('selClassroom');
    const selTch = document.getElementById('selTeacher');
    if (selCls.options.length) updateCounter('cls');
    if (selTch.options.length) updateCounter('tch');
});
</script>
<?= $this->endSection() ?>