<?php
/**
 * views/menu_management/index.php
 * Versi batch-save: semua perubahan ditampung di local state,
 * baru dikirim sekaligus ke server lewat satu request.
 */
?>
<style>
/* ══════════════ MENU MANAGEMENT — BATCH SAVE VERSION ══════════════ */
.mm-page { padding: 20px 0 60px; }

/* Stat cards */
.mm-stats { display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:10px; margin-bottom:20px; }
.mm-stat-card { background:var(--bs-white,#fff); border:1px solid #e9ecef; border-radius:10px; padding:14px 16px; text-align:center; }
.mm-stat-num  { font-size:1.6rem; font-weight:700; line-height:1; }
.mm-stat-label{ font-size:.73rem; color:#6c757d; margin-top:4px; text-transform:uppercase; letter-spacing:.05em; }

/* Role colours */
.role-admin      { color:#7c3aed; } .bg-role-admin      { background:#f5f3ff; border-color:#c4b5fd!important; }
.role-ketua_rt   { color:#0891b2; } .bg-role-ketua_rt   { background:#e0f7fa; border-color:#67e8f9!important; }
.role-sekretaris { color:#16a34a; } .bg-role-sekretaris { background:#f0fdf4; border-color:#86efac!important; }
.role-bendahara  { color:#d97706; } .bg-role-bendahara  { background:#fffbeb; border-color:#fcd34d!important; }
.role-warga      { color:#dc2626; } .bg-role-warga      { background:#fff1f2; border-color:#fca5a5!important; }

/* Role filter tabs */
.role-tabs { display:flex; gap:6px; flex-wrap:wrap; margin-bottom:20px; }
.role-tab {
    padding:6px 14px; border-radius:20px; font-size:.8rem; font-weight:600;
    border:1.5px solid #e9ecef; background:#fff; cursor:pointer; transition:all .15s;
}
.role-tab.active { color:#fff!important; }
.role-tab[data-role="all"].active         { background:#343a40; border-color:#343a40; }
.role-tab[data-role="admin"].active       { background:#7c3aed; border-color:#7c3aed; }
.role-tab[data-role="ketua_rt"].active    { background:#0891b2; border-color:#0891b2; }
.role-tab[data-role="sekretaris"].active  { background:#16a34a; border-color:#16a34a; }
.role-tab[data-role="bendahara"].active   { background:#d97706; border-color:#d97706; }
.role-tab[data-role="warga"].active       { background:#dc2626; border-color:#dc2626; }

/* Matrix table */
.mm-table-wrap { overflow-x:auto; border-radius:12px; border:1px solid #e9ecef; }
.mm-table { width:100%; border-collapse:collapse; min-width:900px; }
.mm-table thead th {
    background:#f8f9fa; padding:10px 12px; font-size:.75rem; font-weight:700;
    text-transform:uppercase; letter-spacing:.06em; color:#6c757d;
    border-bottom:1px solid #e9ecef; white-space:nowrap;
}
.mm-table thead th:first-child { text-align:left; min-width:220px; }
.mm-table thead .role-group-header { border-left:2px solid #e9ecef; padding:8px; text-align:center; font-size:.7rem; }
.mm-table tbody tr { border-bottom:1px solid #f3f4f6; transition:background .1s; }
.mm-table tbody tr:hover { background:#fafafa; }
.mm-table tbody tr.parent-row { background:#f8f9fb; }
.mm-table tbody tr.parent-row td:first-child { font-weight:700; font-size:.85rem; }
.mm-table tbody tr.child-row td:first-child { padding-left:32px; font-size:.82rem; }
.mm-table td { padding:10px 12px; vertical-align:middle; }
.mm-table td.perm-cell { border-left:1px solid #f3f4f6; text-align:center; }
.mm-table td.role-section-start { border-left:2px solid #e9ecef; }

/* ── Permission toggle ── */
.perm-toggle {
    width:34px; height:18px; border-radius:9px; border:none;
    background:#e2e8f0; position:relative; cursor:pointer;
    transition:background .2s; display:inline-block; vertical-align:middle;
}
.perm-toggle::after {
    content:''; position:absolute; top:2px; left:2px;
    width:14px; height:14px; border-radius:50%; background:#fff;
    transition:transform .2s;
}
/* States: saved-on / saved-off / dirty-on / dirty-off */
.perm-toggle.on        { background:#22c55e; }
.perm-toggle.off       { background:#e2e8f0; }
.perm-toggle.on::after  { transform:translateX(16px); }

/* Dirty (belum disimpan) → kuning/amber */
.perm-toggle.dirty.on  { background:#f59e0b; }
.perm-toggle.dirty.off { background:#fde68a; }
.perm-toggle.dirty.off::after { background:#f59e0b; }

/* Module label & badges */
.mod-label { display:flex; align-items:center; gap:8px; }
.mod-label i { font-size:.95rem; color:#9ca3af; }
.badge-off { font-size:.6rem; padding:2px 6px; background:#fee2e2; color:#dc2626; border-radius:4px; font-weight:600; }
.section-label { font-size:.7rem; font-weight:700; color:#6c757d; text-transform:uppercase; letter-spacing:.08em; }

/* Active module toggle */
.mod-active-toggle { display:inline-flex; align-items:center; gap:6px; font-size:.75rem; cursor:pointer; color:#9ca3af; }
.mod-active-toggle input { display:none; }
.mod-active-track { width:36px; height:20px; border-radius:10px; background:#e2e8f0; position:relative; transition:background .2s; flex-shrink:0; }
.mod-active-toggle input:checked + .mod-active-track { background:#0d9488; }
.mod-active-track::after { content:''; position:absolute; top:3px; left:3px; width:14px; height:14px; border-radius:50%; background:#fff; transition:transform .2s; }
.mod-active-toggle input:checked + .mod-active-track::after { transform:translateX(16px); }

/* Action buttons */
.btn-mm       { padding:5px 10px; font-size:.75rem; border-radius:6px; border:1px solid; cursor:pointer; text-decoration:none!important; }
.btn-mm-edit  { background:#eff6ff; border-color:#bfdbfe; color:#1d4ed8; }
.btn-mm-del   { background:#fff1f2; border-color:#fecaca; color:#dc2626; }
.btn-mm-edit:hover { background:#dbeafe; }
.btn-mm-del:hover  { background:#fee2e2; }

/* Bulk toolbar */
.mm-toolbar {
    display:flex; gap:10px; flex-wrap:wrap; align-items:center;
    padding:12px 16px; background:#f8f9fa; border-radius:10px;
    margin-bottom:16px; font-size:.82rem;
}
.mm-toolbar label { color:#6c757d; }
.mm-toolbar select { font-size:.8rem; padding:4px 8px; border:1px solid #d1d5db; border-radius:6px; background:#fff; }
.mm-toolbar .sep { color:#d1d5db; }

/* ══ SAVE BAR (sticky bottom) ══ */
#mm-save-bar {
    position:sticky; bottom:0; z-index:100;
    background:#fff; border-top:1px solid #e9ecef;
    padding:12px 20px;
    display:flex; align-items:center; justify-content:space-between; gap:12px;
    flex-wrap:wrap;
    box-shadow:0 -4px 16px rgba(0,0,0,.06);
    border-radius:0 0 12px 12px;
    transition:opacity .2s, transform .2s;
}
#mm-save-bar.hidden { display:none; }
#mm-save-bar .save-info { font-size:.85rem; color:#6c757d; }
#mm-save-bar .save-info strong { color:#d97706; font-weight:700; }
#mm-save-bar .save-actions { display:flex; gap:8px; }
.btn-save-all {
    padding:8px 20px; font-size:.85rem; font-weight:600;
    border-radius:8px; border:none; cursor:pointer;
    background:#22c55e; color:#fff; transition:opacity .15s;
}
.btn-save-all:disabled { opacity:.5; cursor:not-allowed; }
.btn-discard {
    padding:8px 14px; font-size:.82rem;
    border-radius:8px; border:1px solid #e9ecef;
    background:#fff; cursor:pointer; color:#6c757d;
}
.btn-discard:hover { background:#f8f9fa; }

/* Toast */
#mm-toast {
    position:fixed; bottom:80px; right:24px; z-index:9999;
    padding:12px 20px; border-radius:10px; font-size:.85rem; font-weight:500;
    box-shadow:0 4px 20px rgba(0,0,0,.12); display:none;
    animation:slideUp .25s ease;
}
@keyframes slideUp { from{transform:translateY(20px);opacity:0} to{transform:translateY(0);opacity:1} }
#mm-toast.success { background:#dcfce7; color:#15803d; border:1px solid #86efac; }
#mm-toast.error   { background:#fee2e2; color:#dc2626;  border:1px solid #fca5a5; }
#mm-toast.warning { background:#fef3c7; color:#d97706;  border:1px solid #fcd34d; }

@media(max-width:767px) {
    .mm-table { min-width:700px; }
    .mm-stats { grid-template-columns:repeat(3,1fr); }
}
</style>

<div class="container-fluid mm-page">

    <!-- Header -->
    <div class="d-flex align-items-center justify-content-between mb-3 flex-wrap gap-2">
        <div>
            <h4 class="mb-0 fw-bold"><i class="bi bi-shield-lock-fill me-2 text-teal"></i>Pengaturan Menu &amp; Hak Akses</h4>
            <small class="text-muted">Kelola visibilitas menu dan izin CRUD per role pengguna</small>
        </div>
        <a href="<?= base_url('menu-management/tambah-module') ?>" class="btn btn-sm btn-success">
            <i class="bi bi-plus-circle me-1"></i> Tambah Modul
        </a>
    </div>

    <!-- Flash messages -->
    <?php if ($this->session->flashdata('success')): ?>
    <div class="alert alert-success alert-dismissible"><i class="bi bi-check-circle me-2"></i><?= $this->session->flashdata('success') ?><button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>
    <?php endif; ?>
    <?php if ($this->session->flashdata('error')): ?>
    <div class="alert alert-danger alert-dismissible"><i class="bi bi-exclamation-triangle me-2"></i><?= $this->session->flashdata('error') ?><button type="button" class="btn-close" data-bs-dismiss="alert"></button></div>
    <?php endif; ?>

    <!-- Stat cards -->
    <div class="mm-stats">
        <div class="mm-stat-card">
            <div class="mm-stat-num text-teal"><?= $total_modules ?></div>
            <div class="mm-stat-label">Modul Aktif</div>
        </div>
        <?php
        $role_labels = ['admin'=>'Admin','ketua_rt'=>'Ketua RT','sekretaris'=>'Sekretaris','bendahara'=>'Bendahara','warga'=>'Warga'];
        $role_colors = ['admin'=>'role-admin','ketua_rt'=>'role-ketua_rt','sekretaris'=>'role-sekretaris','bendahara'=>'role-bendahara','warga'=>'role-warga'];
        foreach($stats as $role => $count): ?>
        <div class="mm-stat-card">
            <div class="mm-stat-num <?= $role_colors[$role] ?>"><?= $count ?></div>
            <div class="mm-stat-label"><?= $role_labels[$role] ?></div>
        </div>
        <?php endforeach; ?>
    </div>

    <!-- Role filter tabs -->
    <div class="role-tabs">
        <button class="role-tab active" data-role="all">Semua Role</button>
        <?php foreach($roles as $role): ?>
        <button class="role-tab <?= $role_colors[$role] ?>" data-role="<?= $role ?>"><?= $role_labels[$role] ?></button>
        <?php endforeach; ?>
    </div>

    <!-- Bulk toolbar -->
    <div class="mm-toolbar">
        <label>Salin izin dari:</label>
        <select id="copy-from">
            <option value="">-- pilih role --</option>
            <?php foreach($roles as $r): ?><option value="<?=$r?>"><?=$role_labels[$r]?></option><?php endforeach; ?>
        </select>
        <label>ke:</label>
        <select id="copy-to">
            <option value="">-- pilih role --</option>
            <?php foreach($roles as $r): ?><option value="<?=$r?>"><?=$role_labels[$r]?></option><?php endforeach; ?>
        </select>
        <button class="btn-mm btn-mm-edit" onclick="copyPermissionsLocal()"><i class="bi bi-copy me-1"></i>Salin</button>
        <span class="sep">|</span>
        <label>Reset semua izin role:</label>
        <select id="reset-role">
            <option value="">-- pilih --</option>
            <?php foreach($roles as $r): ?><option value="<?=$r?>"><?=$role_labels[$r]?></option><?php endforeach; ?>
        </select>
        <button class="btn-mm btn-mm-del" onclick="resetPermissionsLocal()"><i class="bi bi-arrow-counterclockwise me-1"></i>Reset</button>
    </div>

    <!-- Matrix Table -->
    <div class="mm-table-wrap">
        <table class="mm-table">
            <thead>
                <tr>
                    <th rowspan="2" class="align-middle">Modul / Menu</th>
                    <th rowspan="2" class="align-middle text-center">Aktif</th>
                    <th rowspan="2" class="align-middle text-center">Aksi</th>
                    <?php foreach($roles as $role): ?>
                    <th colspan="4" class="role-group-header <?= $role_colors[$role] ?> role-col" data-role-col="<?= $role ?>">
                        <?= $role_labels[$role] ?>
                    </th>
                    <?php endforeach; ?>
                </tr>
                <tr>
                    <?php foreach($roles as $role): ?>
                    <th class="perm-cell role-section-start role-col text-center" style="font-size:.65rem" data-role-col="<?= $role ?>">View</th>
                    <th class="perm-cell role-col text-center" style="font-size:.65rem" data-role-col="<?= $role ?>">Create</th>
                    <th class="perm-cell role-col text-center" style="font-size:.65rem" data-role-col="<?= $role ?>">Edit</th>
                    <th class="perm-cell role-col text-center" style="font-size:.65rem" data-role-col="<?= $role ?>">Delete</th>
                    <?php endforeach; ?>
                </tr>
            </thead>
            <tbody>
                <?php foreach($parents as $pid => $parent): ?>
                <!-- Parent Row -->
                <tr class="parent-row" data-module-id="<?= $parent->id ?>">
                    <td>
                        <div class="mod-label">
                            <i class="<?= htmlspecialchars($parent->icon) ?>"></i>
                            <span><?= htmlspecialchars($parent->label) ?></span>
                            <?php if(!$parent->is_active): ?><span class="badge-off">Off</span><?php endif; ?>
                        </div>
                        <div class="section-label ms-4 mt-1"><?= htmlspecialchars($parent->slug) ?></div>
                    </td>
                    <td class="text-center">
                        <label class="mod-active-toggle">
                            <input type="checkbox" <?= $parent->is_active ? 'checked' : '' ?>
                                   onchange="toggleModule(<?= $parent->id ?>, this)">
                            <span class="mod-active-track"></span>
                        </label>
                    </td>
                    <td class="text-center">
                        <a href="<?= base_url('menu-management/edit-module/'.$parent->id) ?>" class="btn-mm btn-mm-edit"><i class="bi bi-pencil"></i></a>
                        <?php if(!in_array($parent->slug, ['dashboard','warga','iuran','kas'])): ?>
                        <button class="btn-mm btn-mm-del ms-1" onclick="deleteModule(<?= $parent->id ?>, '<?= htmlspecialchars($parent->label) ?>')"><i class="bi bi-trash"></i></button>
                        <?php endif; ?>
                    </td>
                    <?php foreach($roles as $role): ?>
                    <?php $p = $parent->permissions[$role]; ?>
                    <td class="perm-cell role-section-start role-col" data-role-col="<?= $role ?>">
                        <?= _perm_toggle($parent->id, $role, 'view',   $p->can_view) ?>
                    </td>
                    <td class="perm-cell role-col" data-role-col="<?= $role ?>">
                        <?= _perm_toggle($parent->id, $role, 'create', $p->can_create) ?>
                    </td>
                    <td class="perm-cell role-col" data-role-col="<?= $role ?>">
                        <?= _perm_toggle($parent->id, $role, 'edit',   $p->can_edit) ?>
                    </td>
                    <td class="perm-cell role-col" data-role-col="<?= $role ?>">
                        <?= _perm_toggle($parent->id, $role, 'delete', $p->can_delete) ?>
                    </td>
                    <?php endforeach; ?>
                </tr>

                <!-- Child Rows -->
                <?php if(!empty($children[$pid])): ?>
                <?php foreach($children[$pid] as $child): ?>
                <tr class="child-row" data-module-id="<?= $child->id ?>">
                    <td>
                        <div class="mod-label">
                            <i class="<?= htmlspecialchars($child->icon) ?>" style="color:#adb5bd"></i>
                            <span><?= htmlspecialchars($child->label) ?></span>
                            <?php if(!$child->is_active): ?><span class="badge-off">Off</span><?php endif; ?>
                        </div>
                        <div style="font-size:.68rem;color:#9ca3af;padding-left:4px;"><?= htmlspecialchars($child->slug) ?></div>
                    </td>
                    <td class="text-center">
                        <label class="mod-active-toggle">
                            <input type="checkbox" <?= $child->is_active ? 'checked' : '' ?>
                                   onchange="toggleModule(<?= $child->id ?>, this)">
                            <span class="mod-active-track"></span>
                        </label>
                    </td>
                    <td class="text-center">
                        <a href="<?= base_url('menu-management/edit-module/'.$child->id) ?>" class="btn-mm btn-mm-edit"><i class="bi bi-pencil"></i></a>
                        <button class="btn-mm btn-mm-del ms-1" onclick="deleteModule(<?= $child->id ?>, '<?= htmlspecialchars($child->label) ?>')"><i class="bi bi-trash"></i></button>
                    </td>
                    <?php foreach($roles as $role): ?>
                    <?php $p = $child->permissions[$role]; ?>
                    <td class="perm-cell role-section-start role-col" data-role-col="<?= $role ?>">
                        <?= _perm_toggle($child->id, $role, 'view',   $p->can_view) ?>
                    </td>
                    <td class="perm-cell role-col" data-role-col="<?= $role ?>">
                        <?= _perm_toggle($child->id, $role, 'create', $p->can_create) ?>
                    </td>
                    <td class="perm-cell role-col" data-role-col="<?= $role ?>">
                        <?= _perm_toggle($child->id, $role, 'edit',   $p->can_edit) ?>
                    </td>
                    <td class="perm-cell role-col" data-role-col="<?= $role ?>">
                        <?= _perm_toggle($child->id, $role, 'delete', $p->can_delete) ?>
                    </td>
                    <?php endforeach; ?>
                </tr>
                <?php endforeach; ?>
                <?php endif; ?>
                <?php endforeach; ?>
            </tbody>
        </table>
    </div><!-- /table-wrap -->

    <!-- ══ SAVE BAR ══ -->
    <div id="mm-save-bar" class="hidden">
        <div class="save-info">
            <i class="bi bi-pencil-square me-1" style="color:#d97706"></i>
            Terdapat <strong id="mm-dirty-count">0</strong> perubahan belum disimpan
        </div>
        <div class="save-actions">
            <button class="btn-discard" onclick="discardChanges()">
                <i class="bi bi-x-circle me-1"></i>Buang perubahan
            </button>
            <button class="btn-save-all" id="mm-btn-save" onclick="saveAllChanges()">
                <i class="bi bi-cloud-upload me-1"></i>Simpan semua
            </button>
        </div>
    </div>

</div><!-- /mm-page -->

<!-- Toast -->
<div id="mm-toast"></div>

<?php
function _perm_toggle($module_id, $role, $action, $value) {
    $on = $value ? 'on' : 'off';
    return "<button class=\"perm-toggle $on\"
        data-module=\"$module_id\" data-role=\"$role\" data-action=\"$action\" data-val=\"$value\" data-orig=\"$value\"
        onclick=\"localToggle(this)\" title=\"$action\"></button>";
}
?>

<script>
/* ════════════════════════════════════════════════════
   BATCH-SAVE PERMISSION MATRIX
   Semua klik toggle disimpan ke memori dulu.
   Baru satu request ke server saat "Simpan semua".
   ════════════════════════════════════════════════════ */

const BASE = '<?= base_url() ?>';

/* ── Toast ── */
function showToast(msg, type = 'success') {
    const t = document.getElementById('mm-toast');
    t.textContent = msg;
    t.className = type;
    t.style.display = 'block';
    clearTimeout(t._tmr);
    t._tmr = setTimeout(() => { t.style.display = 'none'; }, 2800);
}

/* ── Klik toggle: ubah state lokal saja, belum ke server ── */
function localToggle(btn) {
    const curVal = parseInt(btn.dataset.val);
    const newVal = curVal ? 0 : 1;
    const role   = btn.dataset.role;

    /* Update dataset value */
    btn.dataset.val = newVal;

    /* Aturan dependensi: matikan view → matikan semua; nyalakan create/edit/delete → nyalakan view */
    const row = btn.closest('tr');
    if (btn.dataset.action === 'view' && newVal === 0) {
        row.querySelectorAll(`.perm-toggle[data-role="${role}"]`).forEach(b => {
            b.dataset.val = 0;
        });
    }
    if (btn.dataset.action !== 'view' && newVal === 1) {
        const viewBtn = row.querySelector(`.perm-toggle[data-role="${role}"][data-action="view"]`);
        if (viewBtn) viewBtn.dataset.val = 1;
    }

    /* Refresh visual semua toggle di baris + role ini */
    row.querySelectorAll(`.perm-toggle[data-role="${role}"]`).forEach(b => {
        const v    = parseInt(b.dataset.val);
        const orig = parseInt(b.dataset.orig);
        const dirty = (v !== orig);
        b.classList.toggle('on',    !!v);
        b.classList.toggle('off',   !v);
        b.classList.toggle('dirty', dirty);
    });

    updateSaveBar();
}

/* ── Hitung semua toggle yang berubah dari nilai aslinya ── */
function countDirty() {
    return document.querySelectorAll('.perm-toggle.dirty').length;
}

/* ── Tampilkan/sembunyikan save bar ── */
function updateSaveBar() {
    const n   = countDirty();
    const bar = document.getElementById('mm-save-bar');
    if (n > 0) {
        bar.classList.remove('hidden');
        document.getElementById('mm-dirty-count').textContent = n;
    } else {
        bar.classList.add('hidden');
    }
}

/* ── Buang semua perubahan (revert ke data-orig) ── */
function discardChanges() {
    document.querySelectorAll('.perm-toggle').forEach(btn => {
        btn.dataset.val = btn.dataset.orig;
        const v = parseInt(btn.dataset.orig);
        btn.classList.toggle('on',    !!v);
        btn.classList.toggle('off',   !v);
        btn.classList.remove('dirty');
    });
    updateSaveBar();
    showToast('Perubahan dibuang', 'warning');
}

/* ── Kumpulkan delta dan kirim satu request ke server ── */
function saveAllChanges() {
    const dirtyBtns = document.querySelectorAll('.perm-toggle.dirty');
    if (!dirtyBtns.length) return;

    /* Kumpulkan per module+role (bisa banyak action dalam satu module+role) */
    const matrix = {}; /* { module_id: { role: { view,create,edit,delete } } } */

    document.querySelectorAll('.perm-toggle').forEach(btn => {
        const mid  = btn.dataset.module;
        const role = btn.dataset.role;
        const act  = btn.dataset.action;
        const val  = parseInt(btn.dataset.val);

        if (!matrix[mid])        matrix[mid] = {};
        if (!matrix[mid][role])  matrix[mid][role] = {};
        matrix[mid][role][act] = val;
    });

    /* Hanya kirim module+role yang ada dirty toggle-nya */
    const dirtyKeys = new Set();
    dirtyBtns.forEach(b => dirtyKeys.add(b.dataset.module + '|' + b.dataset.role));

    const payload = {};
    dirtyKeys.forEach(key => {
        const [mid, role] = key.split('|');
        if (!payload[mid]) payload[mid] = {};
        payload[mid][role] = matrix[mid][role];
    });

    const btn = document.getElementById('mm-btn-save');
    btn.disabled = true;
    btn.innerHTML = '<i class="bi bi-hourglass-split me-1"></i>Menyimpan...';

    fetch(BASE + 'menu-management/save-matrix', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ matrix: payload })
    })
    .then(r => r.json())
    .then(d => {
        // if (d.status === 'ok') {
        //     /* Commit: update data-orig sesuai nilai baru */
        //     document.querySelectorAll('.perm-toggle').forEach(b => {
        //         b.dataset.orig = b.dataset.val;
        //         b.classList.remove('dirty');
        //     });
        //     updateSaveBar();
        //     showToast('Tersimpan — ' + dirtyKeys.size + ' record diperbarui', 'success');
        // } else {
        //     showToast(d.msg || 'Gagal menyimpan', 'error');
        // }

        if (d.status === 'ok') {
    /* Commit: update data-orig sesuai nilai baru */
    document.querySelectorAll('.perm-toggle').forEach(b => {
        b.dataset.orig = b.dataset.val;
        b.classList.remove('dirty');
    });
    updateSaveBar();
    showToast('Tersimpan — ' + dirtyKeys.size + ' record diperbarui', 'success');

    // Reload halaman setelah 1.2 detik agar sidebar & mobile nav
    // ikut memperbarui permission dari database
    setTimeout(() => location.reload(), 1200);
}
    })
    .catch(() => showToast('Error jaringan', 'error'))
    .finally(() => {
        btn.disabled = false;
        btn.innerHTML = '<i class="bi bi-cloud-upload me-1"></i>Simpan semua';
    });
}

/* ── Toggle module active (langsung, tidak butuh batch) ── */
function toggleModule(id, checkbox) {
    fetch(BASE + 'menu-management/toggle-module', {
        method: 'POST',
        headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
        body: new URLSearchParams({ id })
    })
    .then(r => r.json())
    .then(d => {
        if (d.status === 'ok') {
            showToast(d.msg, 'success');
            const row   = checkbox.closest('tr');
            const badge = row.querySelector('.badge-off');
            if (d.is_active && badge)  badge.remove();
            if (!d.is_active && !badge) {
                const label = row.querySelector('.mod-label');
                if (label) label.insertAdjacentHTML('beforeend', '<span class="badge-off">Off</span>');
            }
        } else {
            checkbox.checked = !checkbox.checked;
            showToast(d.msg || 'Gagal', 'error');
        }
    });
}

/* ── Delete module ── */
function deleteModule(id, label) {
    if (!confirm('Hapus modul "' + label + '"?\nSemua permission modul ini juga akan dihapus.')) return;
    window.location = BASE + 'menu-management/hapus-module/' + id;
}

/* ── Copy permissions (lokal, masuk ke state dirty) ── */
function copyPermissionsLocal() {
    const from = document.getElementById('copy-from').value;
    const to   = document.getElementById('copy-to').value;
    if (!from || !to)  { showToast('Pilih role asal dan tujuan', 'error'); return; }
    if (from === to)   { showToast('Role asal dan tujuan harus berbeda', 'error'); return; }
    if (!confirm('Salin semua izin dari ' + from + ' ke ' + to + '?\nPerubahan belum disimpan ke server.')) return;

    /* Ambil semua nilai dari role "from", terapkan ke role "to" secara lokal */
    const table = document.querySelector('.mm-table');
    table.querySelectorAll('tbody tr').forEach(row => {
        const actions = ['view', 'create', 'edit', 'delete'];
        actions.forEach(act => {
            const srcBtn = row.querySelector(`.perm-toggle[data-role="${from}"][data-action="${act}"]`);
            const dstBtn = row.querySelector(`.perm-toggle[data-role="${to}"][data-action="${act}"]`);
            if (!srcBtn || !dstBtn) return;
            dstBtn.dataset.val = srcBtn.dataset.val;
            const v     = parseInt(dstBtn.dataset.val);
            const orig  = parseInt(dstBtn.dataset.orig);
            const dirty = (v !== orig);
            dstBtn.classList.toggle('on',    !!v);
            dstBtn.classList.toggle('off',   !v);
            dstBtn.classList.toggle('dirty', dirty);
        });
    });

    updateSaveBar();
    showToast('Izin disalin ke ' + to + ' — belum tersimpan ke server', 'warning');
}

/* ── Reset permissions (lokal, masuk ke state dirty) ── */
function resetPermissionsLocal() {
    const role = document.getElementById('reset-role').value;
    if (!role) { showToast('Pilih role yang akan direset', 'error'); return; }
    if (!confirm('Reset SEMUA izin role ' + role + ' ke 0 (lokal)?\nHarus klik Simpan untuk berlaku ke server.')) return;

    document.querySelectorAll(`.perm-toggle[data-role="${role}"]`).forEach(btn => {
        btn.dataset.val = 0;
        const orig  = parseInt(btn.dataset.orig);
        const dirty = (orig !== 0);
        btn.classList.remove('on');
        btn.classList.add('off');
        btn.classList.toggle('dirty', dirty);
    });

    updateSaveBar();
    showToast('Izin ' + role + ' di-reset — belum tersimpan ke server', 'warning');
}

/* ── Role column filter ── */
document.querySelectorAll('.role-tab').forEach(btn => {
    btn.addEventListener('click', function () {
        document.querySelectorAll('.role-tab').forEach(b => b.classList.remove('active'));
        this.classList.add('active');
        const role = this.dataset.role;
        document.querySelectorAll('.role-col').forEach(c => {
            c.style.display = (role === 'all' || c.dataset.roleCol === role) ? '' : 'none';
        });
    });
});
</script>