<?php
    // Force browser to revalidate HTML on every visit so mtime-versioned CSS URLs
    // are always discovered fresh (no hard-refresh needed after CSS edits).
    header('Cache-Control: no-cache, must-revalidate');
    header('Pragma: no-cache');
    header('Expires: 0');
?>
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
    <meta http-equiv="Pragma" content="no-cache">
    <title><?= SITE_TITLE; ?> · <?= $this->v('page_title', 'Dashboard'); ?></title>
    <link rel="icon" href="<?= PROOT; ?>images/favicon.svg" type="image/svg+xml">
    <link rel="apple-touch-icon" href="<?= PROOT; ?>images/logo-mark.svg">
    <link rel="stylesheet" href="<?= PROOT; ?>js/Olibs/bootstrap/bootstrap.min.css">
    <link rel="stylesheet" href="<?= PROOT; ?>js/Olibs/fontawesome/css/all.min.css">
    <!-- Order matters: rsflow.css defines base tokens; pacific.css overrides
         them to the client's palette; custom.css is per-view tweaks. -->
    <link rel="stylesheet" href="<?= PROOT; ?>css/rsflow.css?v=<?= @filemtime(ROOT . '/css/rsflow.css') ?: '1'; ?>">
    <link rel="stylesheet" href="<?= PROOT; ?>css/pacific.css?v=<?= @filemtime(ROOT . '/css/pacific.css') ?: '1'; ?>">
    <link rel="stylesheet" href="<?= PROOT; ?>css/custom.css?v=<?= @filemtime(ROOT . '/css/custom.css') ?: '1'; ?>">
    <link rel="stylesheet" href="<?= PROOT; ?>js/Olibs/jquery-confirm/jquery-confirm.min.css">
    <script src="<?= PROOT; ?>js/Olibs/jquery/jquery-3.7.1.min.js"></script>
    <script src="<?= PROOT; ?>js/Olibs/bootstrap/bootstrap.bundle.min.js"></script>
    <script src="<?= PROOT; ?>js/Olibs/jquery-confirm/jquery-confirm.min.js"></script>
    <script src="<?= PROOT; ?>js/Olibs/cleave/cleave.min.js"></script>
    <script src="<?= PROOT; ?>js/Olibs/rsToast.js"></script>
    <!-- ApexCharts + the Pacific chart shell — loaded globally so every page
         can call new PacificChart(...) without another script tag. Small
         cost (~150 KB gzipped) traded for zero-boilerplate charts across
         seven role dashboards. -->
    <script src="https://cdn.jsdelivr.net/npm/apexcharts@3.49.1/dist/apexcharts.min.js"></script>
    <script src="<?= PROOT; ?>js/pacific-chart.js?v=<?= @filemtime(ROOT . '/js/pacific-chart.js') ?: '1'; ?>"></script>
    <?= $this->content('head'); ?>
</head>
<body>
<?php
    $roleSlug = Controller::currentRoleSlug();
    $roleName = $_SESSION['user_group_name'] ?? '';
    $fullName = $_SESSION['full_name']       ?? $_SESSION['username'] ?? '';
?>
<div class="rs-wrapper">

    <!-- ── Sidebar ─────────────────────────────────────────────────────────── -->
    <aside class="rs-sidebar" id="rsSidebar">
        <a href="<?= PROOT; ?>Dashboard" class="rs-sidebar-brand" style="display:block;padding:16px 18px 14px;">
            <img src="<?= PROOT; ?>images/logo.png" alt="Pacific Group" class="rs-brand-full" style="max-height:38px;width:auto;display:block;">
            <img src="<?= PROOT; ?>images/logo-mark.svg" alt="Pacific Group" class="rs-brand-mark" style="max-height:32px;width:32px;display:none;margin:0 auto;">
            <div class="brand-sub" style="font-size:.6rem;letter-spacing:.16em;text-transform:uppercase;color:var(--pacific-muted);margin-top:8px;font-weight:500;"><?= htmlspecialchars($roleName); ?></div>
        </a>

        <div class="rs-nav-search">
            <i class="fas fa-search rs-nav-search-ico"></i>
            <input type="text" id="rsNavSearch" placeholder="Search menu…" autocomplete="off" aria-label="Search menu">
            <i class="fas fa-times rs-nav-search-clear" id="rsNavSearchClear" title="Clear"></i>
        </div>

        <nav class="rs-nav">
            <?php
                $sidebarFile = ROOT . DS . 'app' . DS . 'views' . DS . 'layouts' . DS . 'partials' . DS . '_sidebar_' . $roleSlug . '.php';
                if (!file_exists($sidebarFile)) {
                    $sidebarFile = ROOT . DS . 'app' . DS . 'views' . DS . 'layouts' . DS . 'partials' . DS . '_sidebar_default.php';
                }
                include $sidebarFile;
            ?>
        </nav>
    </aside>

    <!-- ── Mobile sidebar backdrop (only visible when drawer open) ────────── -->
    <div id="rsSidebarBackdrop" class="rs-sidebar-backdrop" aria-hidden="true"></div>

    <!-- ── Main area ──────────────────────────────────────────────────────── -->
    <div class="rs-main">
        <?php include ROOT . DS . 'app' . DS . 'views' . DS . 'layouts' . DS . 'partials' . DS . '_topnav.php'; ?>

        <main class="rs-content p-3">
            <?= $this->content('body'); ?>
        </main>
    </div>
</div>

<script>
// ── Mobile sidebar toggle (hamburger + backdrop + link autoclose) ──
(function () {
    const sidebar  = document.getElementById('rsSidebar');
    const backdrop = document.getElementById('rsSidebarBackdrop');
    const btn      = document.getElementById('rsHamburger');
    if (!sidebar || !backdrop || !btn) return;

    function open()  { sidebar.classList.add('mobile-open'); backdrop.classList.add('show'); document.body.classList.add('rs-drawer-open'); btn.setAttribute('aria-expanded', 'true'); }
    function close() { sidebar.classList.remove('mobile-open'); backdrop.classList.remove('show'); document.body.classList.remove('rs-drawer-open'); btn.setAttribute('aria-expanded', 'false'); }
    function toggle(){ sidebar.classList.contains('mobile-open') ? close() : open(); }

    btn.addEventListener('click', toggle);
    backdrop.addEventListener('click', close);

    // Auto-close after tapping a nav link on mobile — otherwise the drawer stays
    // covering the page the user just navigated to.
    sidebar.querySelectorAll('.rs-nav-link').forEach(function (a) {
        a.addEventListener('click', function () {
            if (window.matchMedia('(max-width: 991.98px)').matches) close();
        });
    });

    // Close on ESC
    document.addEventListener('keydown', function (e) { if (e.key === 'Escape') close(); });

    // Close if user resizes past the mobile breakpoint
    window.addEventListener('resize', function () { if (window.innerWidth >= 992) close(); });
})();

// Sidebar search: live-filter nav links.
(function () {
    const nav   = document.querySelector('.rs-nav');
    const input = document.getElementById('rsNavSearch');
    const clear = document.getElementById('rsNavSearchClear');
    if (!nav || !input) return;

    function apply(q) {
        q = q.trim().toLowerCase();
        const links = nav.querySelectorAll('.rs-nav-link');
        if (!q) {
            nav.classList.remove('is-searching');
            links.forEach(l => l.classList.remove('nav-hidden'));
            nav.querySelectorAll('.rs-nav-section').forEach(s => s.classList.remove('nav-hidden'));
            return;
        }
        nav.classList.add('is-searching');
        links.forEach(l => {
            const text = l.textContent.toLowerCase();
            l.classList.toggle('nav-hidden', text.indexOf(q) === -1);
        });
    }
    input.addEventListener('input', e => apply(e.target.value));
    if (clear) clear.addEventListener('click', () => { input.value = ''; apply(''); input.focus(); });
})();

// ─── Sidebar rail toggle (collapse to icon-only on desktop) ───
// Restore persisted state ASAP so the first paint doesn't flash the
// wrong width; then wire the toggle button.
(function () {
    try {
        if (localStorage.getItem('rsSidebarRail') === '1') {
            document.body.classList.add('rs-sidebar-rail');
        }
    } catch (e) {}

    // Copy each link's <span> text into data-label so the CSS ::after
    // tooltip has something to show once the span is display:none-d.
    document.querySelectorAll('.rs-nav-link').forEach(function (a) {
        var span = a.querySelector('span');
        if (span && !a.getAttribute('data-label')) {
            a.setAttribute('data-label', span.textContent.trim());
        }
    });

    var btn = document.getElementById('rsSidebarCollapse');
    if (!btn) return;
    btn.addEventListener('click', function () {
        var railed = document.body.classList.toggle('rs-sidebar-rail');
        try { localStorage.setItem('rsSidebarRail', railed ? '1' : '0'); } catch (e) {}
        btn.setAttribute('title', railed ? 'Expand menu' : 'Collapse menu');
        btn.setAttribute('aria-label', railed ? 'Expand menu' : 'Collapse menu');
    });
})();

// Sidebar section collapse/expand — click on any .rs-nav-section header toggles
// the immediately-following .rs-nav-section-items. State persisted per-role in
// localStorage so a user's chosen open/closed sections survive page reloads.
(function () {
    const nav = document.querySelector('.rs-nav');
    if (!nav) return;
    const roleKey = 'rsNavCollapsed:' + (document.querySelector('.rs-sidebar-brand .brand-sub')?.textContent?.trim() || 'default');

    // Restore persisted state
    let closed = [];
    try { closed = JSON.parse(localStorage.getItem(roleKey) || '[]'); } catch (e) {}

    // Assign a stable key to each section based on its label text
    const sections = nav.querySelectorAll('.rs-nav-section');
    sections.forEach(sec => {
        const label = (sec.textContent || '').trim().replace(/\s+/g, '_').toLowerCase();
        sec.dataset.rsSection = label;
        sec.style.cursor = 'pointer';
        sec.setAttribute('role', 'button');
        sec.setAttribute('tabindex', '0');
        if (closed.includes(label)) toggle(sec, true);
        sec.addEventListener('click', () => toggle(sec));
        sec.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(sec); } });
    });

    function toggle(sec, forceClose) {
        const items = sec.nextElementSibling;
        if (!items || !items.classList.contains('rs-nav-section-items')) return;
        const willClose = (forceClose === true) ? true : !sec.classList.contains('collapsed');
        sec.classList.toggle('collapsed', willClose);
        items.style.display = willClose ? 'none' : '';
        // Rotate chevron
        const chev = sec.querySelector('.section-chevron');
        if (chev) chev.style.transform = willClose ? 'rotate(-90deg)' : '';
        // Persist
        try {
            let s = JSON.parse(localStorage.getItem(roleKey) || '[]');
            const k = sec.dataset.rsSection;
            if (willClose) { if (!s.includes(k)) s.push(k); }
            else { s = s.filter(x => x !== k); }
            localStorage.setItem(roleKey, JSON.stringify(s));
        } catch (e) {}
    }
})();
</script>
<style>
    /* Chevron rotates smoothly when a section collapses */
    .rs-nav-section .section-chevron { transition: transform .15s ease; margin-left: auto; }
    .rs-nav-section { user-select: none; }
    .rs-nav-section:hover { opacity: .85; }

    /* ─── Sidebar collapse toggle ───────────────────────────────────────
       Desktop-only rail mode. The trigger lives in the topbar (see
       _topnav.php: #rsSidebarCollapse). Clicking adds .rs-sidebar-rail
       to <body>, which overrides --rs-sidebar-w and shrinks both the
       sidebar and the main content's margin-left in one step.
       State persists in localStorage under 'rsSidebarRail'. */
    .rs-sidebar { transition: width .18s ease; }
    .rs-main { transition: margin-left .18s ease; }
    .rs-topbar-icon-btn {
        width: 30px; height: 30px; border-radius: 6px;
        border: 1px solid transparent;
        background: transparent;
        color: var(--pacific-muted, #6B7484);
        cursor: pointer; align-items: center; justify-content: center;
        font-size: 14px; padding: 0;
        transition: background .15s, color .15s;
    }
    .rs-topbar-icon-btn:hover {
        background: var(--pacific-tint, #EBEFFA);
        color: var(--pacific-navy, #2626F5);
    }

    /* ── Rail (collapsed) state — desktop only ─────────────────────
       rsflow computes both the sidebar width AND the main content's
       margin-left from --rs-sidebar-w. Overriding that variable at
       :root cascades to both — one truth, no fight. */
    @media (min-width: 992px) {
        body.rs-sidebar-rail { --rs-sidebar-w: 68px; }
        body.rs-sidebar-rail .rs-sidebar-collapse-btn i { transform: rotate(180deg); }

        /* Hide text labels + section headers + search + brand tagline */
        body.rs-sidebar-rail .rs-nav-link > span,
        body.rs-sidebar-rail .rs-nav-section,
        body.rs-sidebar-rail .rs-nav-search,
        body.rs-sidebar-rail .brand-sub,
        body.rs-sidebar-rail .rs-brand-full { display: none !important; }

        /* Swap full logo for the mark */
        body.rs-sidebar-rail .rs-brand-mark { display: block !important; }
        body.rs-sidebar-rail .rs-sidebar-brand { padding: 14px 8px 12px !important; text-align: center; }

        /* Icon-only nav links */
        body.rs-sidebar-rail .rs-nav-link {
            justify-content: center;
            padding: 10px 0 !important;
            position: relative;
        }
        body.rs-sidebar-rail .rs-nav-link i {
            margin: 0 !important;
            font-size: 15px;
        }

        /* Hover tooltip — the collapsed link shows the label as a floating
           chip on the right side. Uses data-label populated by JS from the
           original span text (survives the display:none). */
        body.rs-sidebar-rail .rs-nav-link:hover::after {
            content: attr(data-label);
            position: absolute; left: calc(100% + 6px); top: 50%;
            transform: translateY(-50%);
            background: var(--pacific-ink, #0F1220);
            color: #fff;
            padding: 5px 10px; border-radius: 4px;
            font-size: 12px; white-space: nowrap;
            box-shadow: 0 4px 12px -2px rgba(15,18,32,.25);
            pointer-events: none; z-index: 9999;
        }

        /* Section dividers as hairlines in rail mode (a small marker
           between sections so grouped links stay visually chunked) */
        body.rs-sidebar-rail .rs-nav-section-items {
            border-top: 1px solid var(--rs-border, #E2E7EF);
            margin-top: 6px; padding-top: 6px;
        }
        body.rs-sidebar-rail .rs-nav-section-items:first-child { border-top: none; }
    }
</style>
<?= $this->content('section_js'); ?>
</body>
</html>
