<?php
/**
 * shared/components/sidebar.php
 * Menú lateral dinámico del ERP generado desde ModuleRegistry.
 *
 * DEPENDENCIAS:
 *   - config/config.php      (sesión iniciada, SYSTEM_MODULES disponible)
 *   - core/Rbac.php          (hasModule())
 *   - core/ModuleRegistry.php (forSidebar())
 *
 * Carga ModuleRegistry si aún no está disponible (compatibilidad con
 * archivos lab_*.php que incluyen este sidebar directamente).
 */

// Cargar ModuleRegistry si no está ya (cuando el sidebar se incluye desde legacy files)
if (!class_exists('ModuleRegistry', false)) {
    // Asegurar APP_ROOT para que loadFromFiles() funcione
    if (!defined('APP_ROOT')) {
        define('APP_ROOT', realpath(__DIR__ . '/../../'));
    }
    $__mrFile = defined('APP_ROOT')
        ? APP_ROOT . '/core/ModuleRegistry.php'
        : __DIR__ . '/../../core/ModuleRegistry.php';
    if (file_exists($__mrFile)) {
        require_once $__mrFile;
    }
}

// ── Brand color + logo desde DB ──────────────────────────────────────────────
if (!defined('_SIDEBAR_BRAND_INJECTED')) {
    define('_SIDEBAR_BRAND_INJECTED', true);
    $_sb_brand      = '#1565c0';
    $_sb_brand_dark = '#0d47a1';
    $_sb_logo       = '';
    $_sb_lab_nombre = '';
    try {
        if (class_exists('Database', false)) {
            $__cfgs = Database::getInstance()->fetchAll(
                "SELECT clave, valor FROM lab_config WHERE clave IN ('doc_color','doc_logo_base64','empresa_nombre')"
            );
            foreach ($__cfgs as $__r) {
                if ($__r['clave'] === 'doc_color' && preg_match('/^#[0-9a-fA-F]{3,8}$/', $__r['valor'])) {
                    $_sb_brand = $__r['valor'];
                } elseif ($__r['clave'] === 'doc_logo_base64' && !empty($__r['valor'])) {
                    $_sb_logo = $__r['valor'];
                } elseif ($__r['clave'] === 'empresa_nombre') {
                    $_sb_lab_nombre = $__r['valor'];
                }
            }
            $_sb_hex = ltrim($_sb_brand, '#');
            $_sb_brand_dark = sprintf('#%02x%02x%02x',
                max(0, hexdec(substr($_sb_hex, 0, 2)) - 40),
                max(0, hexdec(substr($_sb_hex, 2, 2)) - 40),
                max(0, hexdec(substr($_sb_hex, 4, 2)) - 40)
            );
        }
    } catch (\Throwable $_) {}
    echo "<style>:root{--brand:{$_sb_brand};--brand-dark:{$_sb_brand_dark}}</style>\n";
    // Dark mode: activa Bootstrap 5.3 data-bs-theme si el head de la página no lo hizo ya
    if (!defined('_DM_SCRIPT_INJECTED')) {
        define('_DM_SCRIPT_INJECTED', true);
        echo '<script>(function(){if(document.documentElement.hasAttribute("data-bs-theme"))return;try{var m=window.matchMedia("(prefers-color-scheme: dark)");function a(d){document.documentElement.setAttribute("data-bs-theme",d?"dark":"light");}a(m.matches);m.addEventListener("change",function(e){a(e.matches);});}catch(e){}})();</script>' . "\n";
    }
}

// Ruta del script que está siendo cargado actualmente
$_current_script = basename($_SERVER['PHP_SELF']);

/**
 * Retorna 'active' si la URL o script actual coincide con la ruta dada.
 */
$_isActive = function (string $route) use ($_current_script): string {
    if ($route === '') return '';
    $parsed    = parse_url($route);
    $routeBase = basename($parsed['path'] ?? '');

    // Rutas ERP con query params: comparar script Y cada param de la ruta
    if (!empty($parsed['query'])) {
        $uriParsed = parse_url($_SERVER['REQUEST_URI'] ?? '');
        if ($routeBase !== basename($uriParsed['path'] ?? '')) return '';
        parse_str($parsed['query'], $routeParams);
        parse_str($uriParsed['query'] ?? '', $uriParams);
        foreach ($routeParams as $k => $v) {
            if (($uriParams[$k] ?? null) !== $v) return '';
        }
        return ' active';
    }

    // Rutas directas como /lab_domicilios.php
    return $routeBase === $_current_script ? ' active' : '';
};

$_sb_display_name = $_sb_lab_nombre ?: 'Panel ERP';

// Nombre del usuario para el pie del sidebar
$_user_name = $_SESSION['admin_user']['full_name']
    ?? $_SESSION['admin_user']['username']
    ?? 'Usuario';
$_user_role = $_SESSION['admin_user']['role'] ?? 'admin';

// Mapa de roles a etiqueta legible
$_role_label = [
    'superadmin'    => 'Super Admin',
    'admin'         => 'Administrador',
    'recepcionista' => 'Recepcionista',
    'bacteriologo'  => 'Bacteriólogo',
    'enfermero'     => 'Enfermero',
    'supervisor'    => 'Supervisor',
    'operador_bot'  => 'Operador Bot',
    'readonly'      => 'Solo Lectura',
][$_user_role] ?? ucfirst($_user_role);

// Base URL para rutas relativas
$_base = defined('APP_URL') ? rtrim(APP_URL, '/') : '';
?>
<nav class="sidebar" id="erp-sidebar">

    <div class="sidebar-header">
        <?php if ($_sb_logo): ?>
            <img src="<?= htmlspecialchars($_sb_logo, ENT_QUOTES, 'UTF-8') ?>"
                 alt="Logo" class="sb-logo-img">
        <?php else: ?>
            <div class="sb-logo-fallback">
                <i class="fas fa-flask"></i>
            </div>
        <?php endif; ?>
        <div class="sb-brand-name"><?= htmlspecialchars($_sb_display_name, ENT_QUOTES, 'UTF-8') ?></div>
        <a href="<?= $_base ?>/lab_configuracion.php" class="sb-config-btn" title="Configuración">
            <i class="fas fa-gear"></i>
        </a>
    </div>

    <!-- Buscador de menú -->
    <div class="sb-search-wrap">
        <i class="fas fa-search sb-search-icon"></i>
        <input type="text" id="sbSearch" class="sb-search" placeholder="Buscar módulo…"
               oninput="sbFilter(this.value)" autocomplete="off">
    </div>

    <ul class="sidebar-menu" id="sb-menu">

<?php
// ── Paleta de colores por categoría ────────────────────────────────────────
$_catPalette = [
    'lab'         => '#60a5fa',
    'bot'         => '#4ade80',
    'turnero'     => '#fbbf24',
    'clinico'     => '#c084fc',
    'formularios' => '#22d3ee',
    'sistema'     => '#94a3b8',
];

// ── Renderizado dinámico desde ModuleRegistry ───────────────────────────────
if (class_exists('ModuleRegistry', false)) {
    $sidebarGroups = ModuleRegistry::forSidebar();

    foreach ($sidebarGroups as $catKey => $catData):
        if (empty($catData['modules'])) continue;

        // Detectar si algún link de esta categoría está activo (para auto-expandir)
        $_catHasActive = false;
        foreach ($catData['modules'] as $__mod) {
            $__links = $__mod['links'] ?? [];
            if (!empty($__links)) {
                foreach ($__links as $__lnk) {
                    if ($_isActive($__lnk['route']) !== '') { $_catHasActive = true; break 2; }
                }
            } else {
                $__route = $__mod['route'] ?? '';
                if ($__route && $_isActive($__route) !== '') { $_catHasActive = true; break; }
            }
        }
        $catId    = 'sb-cat-' . htmlspecialchars($catKey, ENT_QUOTES, 'UTF-8');
        $_catColor = $_catPalette[$catKey] ?? '#94a3b8';
?>
        <li class="sidebar-section<?= $_catHasActive ? ' has-active' : '' ?>"
            data-cat="<?= $catId ?>"
            style="--cat-color:<?= $_catColor ?>"
            onclick="sbToggleCat('<?= $catId ?>',this,event)">
            <span class="sb-cat-label">
                <i class="<?= htmlspecialchars($catData['icon'], ENT_QUOTES, 'UTF-8') ?> me-1"></i>
                <?= htmlspecialchars($catData['label'], ENT_QUOTES, 'UTF-8') ?>
            </span>
            <i class="fas fa-chevron-down sb-chevron"></i>
        </li>
        <li class="sb-group" id="<?= $catId ?>" style="--cat-color:<?= $_catColor ?>">
            <ul>
<?php   foreach ($catData['modules'] as $slug => $mod):
            $links = $mod['links'] ?? [];
            if (!empty($links)):
                foreach ($links as $lnk):
                    $href   = $_base . $lnk['route'];
                    $active = $_isActive($lnk['route']);
?>
                <li><a href="<?= htmlspecialchars($href, ENT_QUOTES, 'UTF-8') ?>"
                       class="nav-link<?= $active ?>"
                       <?= !empty($lnk['target']) ? 'target="' . htmlspecialchars($lnk['target'], ENT_QUOTES, 'UTF-8') . '"' : '' ?>>
                    <i class="<?= htmlspecialchars($lnk['icon'], ENT_QUOTES, 'UTF-8') ?>"></i>
                    <?= htmlspecialchars($lnk['name'], ENT_QUOTES, 'UTF-8') ?></a></li>
<?php       endforeach;
            else:
                $route  = $mod['route'] ?? '';
                $href   = $route ? $_base . $route : '#';
                $active = $route ? $_isActive($route) : '';
?>
                <li><a href="<?= htmlspecialchars($href, ENT_QUOTES, 'UTF-8') ?>"
                       class="nav-link<?= $active ?>">
                    <i class="<?= htmlspecialchars($mod['icon'], ENT_QUOTES, 'UTF-8') ?>"></i>
                    <?= htmlspecialchars($mod['name'], ENT_QUOTES, 'UTF-8') ?></a></li>
<?php       endif;
        endforeach; ?>
            </ul>
        </li>

<?php endforeach;

} else {
    // Fallback estático
?>
        <li class="sidebar-section has-active" data-cat="sb-cat-lab" onclick="sbToggleCat('sb-cat-lab',this)">
            <span class="sb-cat-label"><i class="fas fa-house-medical me-1"></i> Laboratorio</span>
            <i class="fas fa-chevron-down sb-chevron"></i>
        </li>
        <li class="sb-group" id="sb-cat-lab"><ul>
        <?php if (function_exists('hasModule') && hasModule('lab_dashboard')): ?>
            <li><a href="lab_dashboard.php" class="nav-link"><i class="fas fa-tachometer-alt"></i> Dashboard</a></li>
        <?php endif; ?>
        <?php if (function_exists('hasModule') && hasModule('lab_domicilios')): ?>
            <li><a href="lab_domicilios.php" class="nav-link"><i class="fas fa-house-medical"></i> Domicilios</a></li>
        <?php endif; ?>
        <?php if (function_exists('hasModule') && hasModule('lab_pacientes')): ?>
            <li><a href="lab_pacientes.php" class="nav-link"><i class="fas fa-users"></i> Pacientes</a></li>
        <?php endif; ?>
        </ul></li>
<?php } ?>

        <!-- Pie -->
        <li class="sidebar-divider"></li>
        <li><a href="<?= $_base ?>/logout.php" class="nav-link logout-link"
               onclick="return confirm('¿Cerrar sesión?')">
            <i class="fas fa-sign-out-alt"></i> Cerrar Sesión</a></li>

    </ul>

    <!-- Información del usuario -->
    <div class="sidebar-user">
        <div class="sidebar-user-name">
            <i class="fas fa-user-circle me-1"></i>
            <?= htmlspecialchars($_user_name, ENT_QUOTES, 'UTF-8') ?>
        </div>
        <div class="sidebar-user-role"><?= htmlspecialchars($_role_label, ENT_QUOTES, 'UTF-8') ?></div>
        <div style="font-size:.68rem;color:#94a3b8;margin-top:3px;letter-spacing:.02em" title="ID único de este navegador">
            <i class="fas fa-fingerprint me-1"></i><span id="sb-device-token" style="font-family:monospace">—</span>
        </div>
    </div>

</nav>
<script>
(function() {
    function getOrCreateToken() {
        var t = localStorage.getItem('turnero_device_token');
        if (!t) {
            t = typeof crypto !== 'undefined' && crypto.randomUUID
                ? crypto.randomUUID()
                : 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
                    var r = Math.random() * 16 | 0;
                    return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
                });
            localStorage.setItem('turnero_device_token', t);
        }
        // Setear como cookie para que PHP lo lea en cada request
        document.cookie = 'turnero_token=' + t + '; path=/; SameSite=Strict; max-age=31536000';
        return t;
    }
    function init() {
        var token = getOrCreateToken();
        var el = document.getElementById('sb-device-token');
        if (el) el.textContent = token.substring(0, 8) + '…';
        // Exponer globalmente para que configuracion.php lo use
        window._turneroDeviceToken = token;
    }
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();
</script>

<style>
/* ── Header con logo ────────────────────────────────── */
.sidebar-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: 18px 16px 14px;
    position: relative;
}
.sb-logo-img {
    max-width: 130px;
    max-height: 64px;
    object-fit: contain;
    background: rgba(255,255,255,.92);
    border-radius: 10px;
    padding: 6px 10px;
}
.sb-logo-fallback {
    width: 52px; height: 52px;
    border-radius: 14px;
    background: rgba(255,255,255,.18);
    display: flex; align-items: center; justify-content: center;
    font-size: 1.5rem; color: #fff;
}
.sb-brand-name {
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: rgba(255,255,255,.80);
    text-align: center;
    line-height: 1.3;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* config en esquina superior derecha */
.sb-config-btn {
    position: absolute;
    top: 10px; right: 10px;
    color: rgba(255,255,255,.55);
    font-size: .9rem;
    padding: 5px 7px;
    border-radius: 6px;
    transition: color .15s, background .15s;
    line-height: 1;
}
.sb-config-btn:hover { color:#fff; background:rgba(255,255,255,.15); }

/* ── Buscador de menú ───────────────────────────────── */
.sb-search-wrap {
    position: relative;
    padding: 10px 14px 6px;
    flex-shrink: 0;
}
.sb-search-icon {
    position: absolute;
    left: 24px;
    top: 50%;
    transform: translateY(-30%);
    color: rgba(255,255,255,.45);
    font-size: .75rem;
    pointer-events: none;
}
.sb-search {
    width: 100%;
    background: rgba(255,255,255,.12);
    border: 1px solid rgba(255,255,255,.18);
    border-radius: 8px;
    color: #fff;
    padding: 6px 10px 6px 28px;
    font-size: .8rem;
    outline: none;
    transition: background .2s, border-color .2s;
}
.sb-search::placeholder { color: rgba(255,255,255,.45); }
.sb-search:focus { background: rgba(255,255,255,.2); border-color: rgba(255,255,255,.4); }

/* ── Acordeón de categorías ─────────────────────────── */
.sidebar-section {
    position: relative;
    display: block;
    text-align: center;
    cursor: pointer;
    user-select: none;
    padding: 8px 30px 6px;
    margin-top: 6px;
    border-radius: 8px 8px 0 0;
    transition: background .15s, border-color .15s;
    border-left: 3px solid transparent;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: rgba(255,255,255,.65);
}
.sidebar-section:hover { background: rgba(255,255,255,.08); color: rgba(255,255,255,.9); }
.sidebar-section.has-active {
    border-left-color: rgba(255,255,255,.7);
    background: rgba(255,255,255,.1);
    color: #fff;
}
.sidebar-section .sb-cat-label { display:inline-flex; align-items:center; gap:5px; }
.sb-chevron {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    font-size: .6rem;
    opacity: .6;
    transition: transform .25s ease;
}
.sidebar-section.collapsed .sb-chevron { transform: translateY(-50%) rotate(-90deg); }

/* Grupo colapsable */
.sb-group {
    overflow: hidden; transition: max-height .28s ease, opacity .2s ease;
    background: color-mix(in srgb, var(--cat-color, transparent) 8%, transparent);
    border-left: 2px solid color-mix(in srgb, var(--cat-color, transparent) 40%, transparent);
    margin-left: 10px;
    border-radius: 0 0 8px 8px;
}
.sb-group > ul { list-style: none; padding: 0 0 4px; margin: 0; }
.sb-group.collapsed { max-height: 0 !important; opacity: 0; pointer-events: none; }
</style>

<script>
(function () {
    var STORE_KEY = 'sb_collapsed_cats';

    function getCollapsed() {
        try { return JSON.parse(localStorage.getItem(STORE_KEY) || '[]'); } catch(_) { return []; }
    }
    function setCollapsed(arr) {
        try { localStorage.setItem(STORE_KEY, JSON.stringify(arr)); } catch(_) {}
    }

    function applyState(groupEl, sectionEl, collapsed, animate) {
        if (collapsed) {
            if (!animate) { groupEl.style.maxHeight = '0'; groupEl.style.opacity = '0'; }
            groupEl.classList.add('collapsed');
            sectionEl.classList.add('collapsed');
        } else {
            groupEl.classList.remove('collapsed');
            sectionEl.classList.remove('collapsed');
            groupEl.style.maxHeight = groupEl.scrollHeight + 'px';
            groupEl.style.opacity   = '1';
        }
    }

    window.sbToggleCat = function(catId, sectionEl, ev) {
        if (ev) { ev.preventDefault(); ev.stopPropagation(); }
        var nav = document.getElementById('erp-sidebar');
        var savedScroll = nav ? nav.scrollTop : 0;

        var group = document.getElementById(catId);
        if (!group) return;
        var isCollapsed = group.classList.contains('collapsed');
        var arr = getCollapsed();
        if (isCollapsed) {
            arr = arr.filter(function(id){ return id !== catId; });
            applyState(group, sectionEl, false, true);
        } else {
            if (arr.indexOf(catId) === -1) arr.push(catId);
            group.style.maxHeight = group.scrollHeight + 'px';
            group.style.opacity   = '1';
            requestAnimationFrame(function(){
                group.classList.add('collapsed');
                sectionEl.classList.add('collapsed');
                group.style.maxHeight = '0';
                group.style.opacity   = '0';
            });
        }
        setCollapsed(arr);

        // Restaurar scroll del sidebar para que no salte al top
        if (nav) { requestAnimationFrame(function(){ nav.scrollTop = savedScroll; }); }
    };

    // ── Buscador de menú ─────────────────────────────────────────
    window.sbFilter = function(q) {
        q = q.trim().toLowerCase();
        var menu = document.getElementById('sb-menu');
        if (!menu) return;

        if (!q) {
            // Restaurar estado guardado
            menu.querySelectorAll('.sb-group').forEach(function(g) {
                g.style.display = '';
            });
            menu.querySelectorAll('.sidebar-section').forEach(function(s) {
                s.style.display = '';
            });
            // Re-aplicar estado colapsado
            var collapsed = getCollapsed();
            menu.querySelectorAll('.sb-group').forEach(function(group) {
                var section = document.querySelector('[data-cat="' + group.id + '"]');
                var hasActive = !!group.querySelector('.nav-link.active');
                var isCol = !hasActive && collapsed.indexOf(group.id) !== -1;
                if (section) applyState(group, section, isCol, false);
            });
            return;
        }

        // Mostrar todos expandidos y filtrar por texto
        menu.querySelectorAll('.sb-group').forEach(function(g) {
            var links     = g.querySelectorAll('.nav-link');
            var anyMatch  = false;
            links.forEach(function(a) {
                var txt = a.textContent.toLowerCase();
                var show = txt.includes(q);
                a.parentElement.style.display = show ? '' : 'none';
                if (show) anyMatch = true;
            });
            // Mostrar/ocultar grupo completo
            g.style.display = anyMatch ? '' : 'none';
            g.style.maxHeight = '2000px';
            g.style.opacity   = '1';
            g.classList.remove('collapsed');
            var section = document.querySelector('[data-cat="' + g.id + '"]');
            if (section) {
                section.style.display = anyMatch ? '' : 'none';
                section.classList.remove('collapsed');
            }
        });
    };

    // Inicializar al cargar — sin animación para evitar flash
    document.addEventListener('DOMContentLoaded', function () {
        var collapsed = getCollapsed();
        // Deshabilitar transición durante init
        var style = document.createElement('style');
        style.id  = '_sb_notrans';
        style.textContent = '.sb-group { transition: none !important; }';
        document.head.appendChild(style);

        document.querySelectorAll('.sb-group').forEach(function(group) {
            var catId   = group.id;
            var section = document.querySelector('[data-cat="' + catId + '"]');
            if (!section) return;
            var hasActive   = !!group.querySelector('.nav-link.active');
            var isCollapsed = !hasActive && collapsed.indexOf(catId) !== -1;
            // Altura real (funciona incluso con overflow:hidden)
            group.style.maxHeight = group.scrollHeight + 'px';
            group.style.opacity   = '1';
            applyState(group, section, isCollapsed, false);
        });

        // Reactivar transición en el próximo frame
        requestAnimationFrame(function() {
            var el = document.getElementById('_sb_notrans');
            if (el) el.remove();
        });

        // Restaurar posición de scroll del sidebar entre páginas
        var nav = document.getElementById('erp-sidebar');
        if (nav) {
            var savedScroll = parseInt(localStorage.getItem('sb_scroll') || '0', 10);
            if (savedScroll) nav.scrollTop = savedScroll;

            // Guardar posición al navegar
            document.querySelectorAll('#erp-sidebar .nav-link').forEach(function(link) {
                link.addEventListener('click', function() {
                    localStorage.setItem('sb_scroll', nav.scrollTop);
                });
            });
        }
    });
})();
</script>
