<?php
/**
 * @intranet-file dashboard.php
 * @intranet-file-version 2026.03.13.1
 * @intranet-file-date 2026-03-13
 * @intranet-file-owner CSIF Intranet
 */
declare(strict_types=1);

ini_set('session.gc_maxlifetime', '3600');
session_start();
require_once __DIR__ . '/common/url.php';
require_once __DIR__ . '/common/user_preferences.php';

if (!intranet_enforce_session_timeout()) {
    header('Location: ' . login_url('expired=1'));
    exit();
}

// 1. Validar sesión
if (!isset($_SESSION['username'])) {
    header('Location: ' . login_url('expired=1'));
    exit();
}

// Recuperar datos de sesión
$userRoles   = $_SESSION['roles'] ?? [];
$primaryRole = $_SESSION['primaryRole'] ?? '';
$userName    = $_SESSION['givenName'] ?? $_SESSION['username'];
$userInitial = strtoupper(substr((string)$userName, 0, 1));

// Normalizar roles a minúsculas para comparar
$userRolesLower = array_map('strtolower', $userRoles);

// 2. Registrar visita a intranet (una vez por sesión)
require_once __DIR__ . '/common/db.php';
require_once __DIR__ . '/common/catalogo_db.php';
require_once __DIR__ . '/common/plugin_store.php';

require_once __DIR__ . '/common/visitas_tracking.php';
// Versión de la intranet (para mostrarla bajo el logo del menú lateral)
$__intranetMeta = @require __DIR__ . '/config/version.php';
$__intranetVersion = (is_array($__intranetMeta) && !empty($__intranetMeta['version'])) ? (string)$__intranetMeta['version'] : '';
$__intranetName = (is_array($__intranetMeta) && !empty($__intranetMeta['name'])) ? (string)$__intranetMeta['name'] : 'Intranet';

function recordIntranetVisit(PDO $pdo, string $username): void
{
    visitas_record_page_view($pdo, $username);
}

try {
    $pdo = db();
    intranet_preferences_ensure_app_registered($pdo);
    $themeMode = intranet_load_session_theme_mode($pdo);
    $menuLayout = intranet_load_session_menu_layout($pdo);
    if (empty($_SESSION['visit_counted'])) {
        recordIntranetVisit($pdo, (string)$_SESSION['username']);
        $_SESSION['visit_counted'] = true;
    }
} catch (Throwable $e) {
    // No reventar el dashboard si la BD falla: opcionalmente loguea
    // error_log($e->getMessage());
}
if (!isset($themeMode)) {
    $themeMode = intranet_load_session_theme_mode();
}
if (!isset($menuLayout)) {
    $menuLayout = intranet_load_session_menu_layout();
}

// 3. Cargar catálogo de apps desde BD
$menuGroups = [];
try {
    $pdo = db();
    core_update_ensure_app_registered($pdo);
    $apps = catalogo_apps_fetch($pdo, true);

    // Agrupar por group_name preservando el orden (ya viene ordenado por group_name, position)
    $byGroup = [];
    $groupIcons = [];
    foreach ($apps as $row) {
        $requiredRoles = catalogo_roles_from_json($row['roles_json'] ?? '');
        if (!catalogo_roles_allow($userRolesLower, $requiredRoles)) {
            continue;
        }

        $g = catalogo_normalize_app_group_name($row['group_name'] ?? 'Mis apps');

        $groupIconSvg = catalogo_normalize_svg_markup($row['group_icon_svg'] ?? null);
        if (!isset($groupIcons[$g]) && $groupIconSvg !== null) {
            $groupIcons[$g] = $groupIconSvg;
        }

        $byGroup[$g][] = [
            'id' => (string)($row['app_id'] ?? ''),
            'name' => (string)($row['name'] ?? ''),
            'url' => (string)($row['url'] ?? ''),
            'description' => (string)($row['description'] ?? ''),
            'icon' => (string)($row['icon'] ?? ''),
            'image' => (string)($row['image'] ?? ''),
            'newTab' => !empty($row['new_tab']),
        ];
    }

    foreach ($byGroup as $g => $appsInGroup) {
        if (empty($appsInGroup)) continue;
        $menuGroups[] = ['group' => $g, 'icon' => $groupIcons[$g] ?? '', 'apps' => $appsInGroup];
    }
} catch (Throwable $e) {
    // Si falla BD, mostramos menú vacío
    $menuGroups = [];
}

// Formatear rol para visualización
function dashboard_menu_group_key(string $groupName): string
{
    $name = catalogo_app_group_key($groupName);

    if ($name === 'home' || $name === 'inicio') {
        return 'home';
    }
    if ($name === 'administracion') {
        return 'admin';
    }
    if ($name === 'generales' || $name === 'general') {
        return 'general';
    }
    if ($name === 'mis apps' || $name === 'mis aplicaciones' || $name === 'herramientas') {
        return 'tools';
    }

    return 'tools';
}

function dashboard_menu_group_id(string $groupName): string
{
    $groupId = catalogo_app_group_key($groupName);
    $groupId = preg_replace('/[^a-z0-9]+/', '-', $groupId);
    $groupId = trim((string)$groupId, '-');
    return $groupId !== '' ? $groupId : 'grupo';
}

function dashboard_menu_group_meta(string $groupName, ?string $customIcon = null): array
{
    $key = dashboard_menu_group_key($groupName);
    $customIcon = catalogo_normalize_svg_markup($customIcon);
    $icons = [
        'home' => '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>',
        'general' => '<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M4 4.5A2.5 2.5 0 0 1 6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5z"></path></svg>',
        'tools' => '<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path></svg>',
        'admin' => '<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.6 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 8.92 4.6 1.65 1.65 0 0 0 10 3.09V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1.08 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9c.24.58.82 1 1.51 1H21a2 2 0 1 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>',
    ];

    return [
        'label' => $key === 'home' ? 'Inicio' : $groupName,
        'icon' => $customIcon ?? ($icons[$key] ?? $icons['tools']),
        'id' => dashboard_menu_group_id($groupName),
    ];
}

$displayRole = str_replace(['app_', 'administradores'], ['', 'Administrador'], (string)$primaryRole);
$displayRole = ucfirst($displayRole);

$allowedFrameSrcs = ['wellcome_context.php' => true];
foreach ($menuGroups as $group) {
    foreach ((array)($group['apps'] ?? []) as $app) {
        if (!empty($app['newTab'])) {
            continue;
        }

        $appId = trim((string)($app['id'] ?? ''));
        if ($appId !== '') {
            $allowedFrameSrcs['go.php?app_id=' . rawurlencode($appId)] = true;
        }

        $appUrl = ltrim(str_replace('\\', '/', trim((string)($app['url'] ?? ''))), '/');
        if ($appUrl !== '') {
            $allowedFrameSrcs[$appUrl] = true;
        }
    }
}

function dashboard_frame_src_allowed(string $src, array $allowedFrameSrcs): bool
{
    $src = trim($src);
    if ($src === '') {
        return false;
    }
    if (isset($allowedFrameSrcs[$src])) {
        return true;
    }

    foreach ($allowedFrameSrcs as $allowed => $_unused) {
        if ($allowed === '' || $allowed === 'wellcome_context.php') {
            continue;
        }
        if (strpos($src, $allowed . '?') === 0) {
            return true;
        }
    }

    return false;
}

$defaultFrameSrc = 'wellcome_context.php';
$requestedFrameSrc = isset($_GET['open']) && is_string($_GET['open']) ? trim((string) $_GET['open']) : '';
if ($requestedFrameSrc !== '') {
    $requestedFrameSrc = rawurldecode($requestedFrameSrc);
    $requestedFrameSrc = preg_replace('~[\x00-\x1F\x7F]+~', '', (string) $requestedFrameSrc);
    $requestedFrameSrc = ltrim(str_replace('\\', '/', $requestedFrameSrc), '/');
    $isSafeFrameSrc = (bool) preg_match('~^[a-zA-Z0-9_./?&=%-]+$~', $requestedFrameSrc)
        && strpos($requestedFrameSrc, '..') === false
        && !preg_match('~^(?:https?:)?//~i', $requestedFrameSrc);
    if ($isSafeFrameSrc && dashboard_frame_src_allowed($requestedFrameSrc, $allowedFrameSrcs)) {
        $defaultFrameSrc = $requestedFrameSrc;
    }
}
?>
<!DOCTYPE html>
<html lang="es" <?= intranet_theme_html_attr($themeMode); ?>>
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Portal Corporativo</title>
    <?= intranet_theme_bootstrap_script_tag($themeMode); ?>
    <link rel="stylesheet" href="styles/css/style.css" />
    <link rel="stylesheet" href="styles/css/theme-vars.css" />
</head>
<body>

<div class="portal-container menu-layout-<?php echo htmlspecialchars($menuLayout); ?>">

    <!-- BARRA LATERAL (SIDEBAR) -->
    <?php if ($menuLayout === 'sidebar'): ?>
    <nav class="sidebar">

        <!-- LOGO CORPORATIVO -->
        <div class="sidebar-logo">
            <img src="styles/images/logob.png" alt="Logo Corporativo">
            <?php if (!empty($__intranetVersion)): ?>
                <div class="sidebar-version" title="<?php echo htmlspecialchars($__intranetName . ' ' . $__intranetVersion); ?>">
                    Versión <?php echo htmlspecialchars($__intranetVersion); ?>
                </div>
            <?php endif; ?>
        </div>

        <div class="sidebar-header">
            <div class="user-info-mini">
                <div class="avatar-mini"><?php echo htmlspecialchars($userInitial); ?></div>
                <div class="user-details">
                    <h3 title="<?php echo htmlspecialchars((string)$userName); ?>">
                        <?php echo htmlspecialchars((string)$userName); ?>
                    </h3>
                    <span><?php echo htmlspecialchars((string)$displayRole); ?></span>
                </div>
            </div>
        </div>

        <div class="nav-menu">
            <?php if (empty($menuGroups)): ?>
                <div style="padding: 1.5rem; color: #94a3b8; font-size: 0.9rem;">
                    No tienes aplicaciones asignadas.
                </div>
            <?php else: ?>

                <!-- Enlace a Inicio -->
                <?php $homeMeta = dashboard_menu_group_meta('home'); ?>
                <a href="wellcome_context.php" target="content-frame" class="nav-item active" data-dashboard-home="1" onclick="setActive(this)">
                    <span class="nav-icon"><?php echo $homeMeta['icon']; ?></span>
                    <span class="nav-text">Inicio</span>
                </a>

                <!-- Bucle de Grupos y Aplicaciones -->
                <?php foreach ($menuGroups as $group): ?>
                    <?php
                    $groupName = (string)($group['group'] ?? 'Grupo');
                    $groupMeta = dashboard_menu_group_meta($groupName, (string)($group['icon'] ?? ''));
                    $groupId = (string)$groupMeta['id'];
                    ?>

                    <div class="nav-group" data-group-id="<?php echo htmlspecialchars($groupId); ?>">
                        <button type="button" class="nav-group-title-toggle" aria-expanded="true">
                            <span class="nav-group-title-main">
                                <span class="nav-group-title-icon" aria-hidden="true"><?php echo $groupMeta['icon']; ?></span>
                                <span class="nav-group-title-text"><?php echo htmlspecialchars($groupName); ?></span>
                            </span>
                            <span class="caret" aria-hidden="true">▾</span>
                        </button>
                        <div class="nav-group-items">

                            <?php foreach ($group['apps'] as $app): ?>
                        <?php
                        // 1) Nueva pestaña vs iframe
                        $isExternal = (!empty($app['newTab']) && $app['newTab'] === true);
                        $target = $isExternal ? '_blank' : 'content-frame';
                        $arrowIcon = $isExternal ? ' <span style="font-size:0.8em; opacity:0.7;">&#8599;</span>' : '';
                        $onClickAction = $isExternal ? '' : 'setActive(this)';

                        // 2) ID obligatorio para contar clics
                        $appId = $app['id'] ?? '';
                        if (!is_string($appId) || $appId === '') {
                            // Si no hay id, no podemos contar correctamente.
                            // Aún así mostramos, pero lo mandamos a la url directa (sin contador).
                            $href = $app['url'] ?? '#';
                        } else {
                            // IMPORTANTE: pasar por go.php para contar clic
                            $href = 'go.php?app_id=' . urlencode($appId);
                        }

                        // 3) Imagen vs icono
                        if (!empty($app['image'])) {
                            $iconContent = '<img src="' . htmlspecialchars((string)$app['image']) . '" alt="App Icon" style="width: 75px; height: 75px; object-fit: contain; display: block; border-radius: 4px;">';
                        } else {
                            $iconContent = $app['icon'] ?? '';
                        }

                        $desc = $app['description'] ?? '';
                        $name = $app['name'] ?? 'Aplicación';
                        ?>

                        <a href="<?php echo htmlspecialchars((string)$href); ?>"
                           target="<?php echo htmlspecialchars((string)$target); ?>"
                           class="nav-item"
                           data-app-id="<?php echo htmlspecialchars((string)$appId); ?>"
                           data-app-url="<?php echo htmlspecialchars((string)($app['url'] ?? '')); ?>"
                           data-app-name="<?php echo htmlspecialchars((string)$name); ?>"
                           title="<?php echo htmlspecialchars((string)$desc); ?>"
                           onclick="<?php echo htmlspecialchars((string)$onClickAction); ?>">

                            <span class="nav-icon">
                                <?php echo $iconContent; ?>
                            </span>
                            <span class="nav-text">
                                <?php echo htmlspecialchars((string)$name) . $arrowIcon; ?>
                            </span>
                        </a>

                            <?php endforeach; ?>

                        </div>
                    </div>
                <?php endforeach; ?>

            <?php endif; ?>
        </div>

        <div class="sidebar-footer">
            <a href="<?= h(app_url('logout.php')) ?>" class="btn-logout-mini" target="_top">
                <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
                     stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
                    <polyline points="16 17 21 12 16 7"></polyline>
                    <line x1="21" y1="12" x2="9" y2="12"></line>
                </svg>
                <span class="nav-text" style="margin-left: 5px;">Cerrar Sesión</span>
            </a>
        </div>
    </nav>
    <?php endif; ?>

    <!-- ÁREA PRINCIPAL -->
    <main class="main-content">

        <?php if ($menuLayout !== 'sidebar'): ?>
            <nav class="dashboard-launcher dashboard-launcher-<?php echo htmlspecialchars($menuLayout); ?>" aria-label="Menu principal">
                <div class="dashboard-launcher-brand">
                    <img src="styles/images/logob.png" alt="Logo Corporativo">
                    <?php if (!empty($__intranetVersion)): ?>
                        <span title="<?php echo htmlspecialchars($__intranetName . ' ' . $__intranetVersion); ?>">v<?php echo htmlspecialchars($__intranetVersion); ?></span>
                    <?php endif; ?>
                </div>

                <div class="dashboard-launcher-actions" role="menubar">
                    <?php $homeMeta = dashboard_menu_group_meta('home'); ?>
                    <a href="wellcome_context.php" target="content-frame" class="launcher-button nav-item active" data-dashboard-home="1" onclick="setActive(this)" title="Inicio">
                        <span class="launcher-icon"><?php echo $homeMeta['icon']; ?></span>
                        <span class="launcher-label"><?php echo htmlspecialchars($homeMeta['label']); ?></span>
                    </a>

                    <?php foreach ($menuGroups as $group): ?>
                        <?php
                        $groupName = (string)($group['group'] ?? 'Grupo');
                        $meta = dashboard_menu_group_meta($groupName, (string)($group['icon'] ?? ''));
                        ?>
                        <button type="button" class="launcher-button launcher-menu-toggle" data-launcher-panel="<?php echo htmlspecialchars((string)$meta['id']); ?>" aria-expanded="false" title="<?php echo htmlspecialchars($meta['label']); ?>">
                            <span class="launcher-icon"><?php echo $meta['icon']; ?></span>
                            <span class="launcher-label"><?php echo htmlspecialchars($meta['label']); ?></span>
                        </button>
                    <?php endforeach; ?>
                </div>

                <div class="dashboard-launcher-user" title="<?php echo htmlspecialchars((string)$userName); ?>">
                    <span class="avatar-mini"><?php echo htmlspecialchars($userInitial); ?></span>
                    <span class="launcher-user-name"><?php echo htmlspecialchars((string)$userName); ?></span>
                    <a href="<?= h(app_url('logout.php')) ?>" class="launcher-logout" target="_top" title="Cerrar sesion">
                        <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none"
                             stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                            <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
                            <polyline points="16 17 21 12 16 7"></polyline>
                            <line x1="21" y1="12" x2="9" y2="12"></line>
                        </svg>
                    </a>
                </div>
            </nav>

            <div class="launcher-panels" aria-live="polite">
                <?php foreach ($menuGroups as $group): ?>
                    <?php
                    $groupName = (string)($group['group'] ?? 'Grupo');
                    $meta = dashboard_menu_group_meta($groupName, (string)($group['icon'] ?? ''));
                    $appsForBucket = (array)($group['apps'] ?? []);
                    ?>
                    <section class="launcher-panel" data-launcher-panel-content="<?php echo htmlspecialchars((string)$meta['id']); ?>" aria-label="<?php echo htmlspecialchars($meta['label']); ?>">
                        <div class="launcher-panel-head">
                            <div>
                                <strong><?php echo htmlspecialchars($meta['label']); ?></strong>
                                <span><?php echo (int)count($appsForBucket); ?> opciones disponibles</span>
                            </div>
                            <button type="button" class="launcher-panel-close" aria-label="Cerrar menu">x</button>
                        </div>
                        <div class="launcher-panel-grid">
                            <?php if (empty($appsForBucket)): ?>
                                <div class="launcher-empty">No tienes opciones asignadas en este grupo.</div>
                            <?php endif; ?>
                            <?php foreach ($appsForBucket as $app): ?>
                                <?php
                                $isExternal = (!empty($app['newTab']) && $app['newTab'] === true);
                                $target = $isExternal ? '_blank' : 'content-frame';
                                $arrowIcon = $isExternal ? ' <span style="font-size:0.8em; opacity:0.7;">&#8599;</span>' : '';
                                $onClickAction = $isExternal ? 'closeLauncherPanels();' : 'setActive(this); closeLauncherPanels();';
                                $appId = $app['id'] ?? '';
                                if (!is_string($appId) || $appId === '') {
                                    $href = $app['url'] ?? '#';
                                } else {
                                    $href = 'go.php?app_id=' . urlencode($appId);
                                }
                                if (!empty($app['image'])) {
                                    $iconContent = '<img src="' . htmlspecialchars((string)$app['image']) . '" alt="" style="width: 40px; height: 40px; object-fit: contain; display: block; border-radius: 4px;">';
                                } else {
                                    $iconContent = $app['icon'] ?? '';
                                }
                                $desc = $app['description'] ?? '';
                                $name = $app['name'] ?? 'Aplicacion';
                                ?>
                                <a href="<?php echo htmlspecialchars((string)$href); ?>"
                                   target="<?php echo htmlspecialchars((string)$target); ?>"
                                   class="launcher-option nav-item"
                                   data-app-id="<?php echo htmlspecialchars((string)$appId); ?>"
                                   data-app-url="<?php echo htmlspecialchars((string)($app['url'] ?? '')); ?>"
                                   data-app-name="<?php echo htmlspecialchars((string)$name); ?>"
                                   title="<?php echo htmlspecialchars((string)$desc); ?>"
                                   onclick="<?php echo htmlspecialchars((string)$onClickAction); ?>">
                                    <span class="nav-icon launcher-option-icon"><?php echo $iconContent; ?></span>
                                    <span class="launcher-option-copy">
                                        <strong><?php echo htmlspecialchars((string)$name) . $arrowIcon; ?></strong>
                                        <?php if (!empty($desc)): ?>
                                            <small><?php echo htmlspecialchars((string)$desc); ?></small>
                                        <?php endif; ?>
                                    </span>
                                </a>
                            <?php endforeach; ?>
                        </div>
                    </section>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>

        <!-- BOTÓN DE MENÚ / TOGGLE -->
        <?php if ($menuLayout === 'sidebar'): ?>
        <button id="sidebarToggle" class="menu-toggle-btn" title="Mostrar/Ocultar Menú">
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"
                 stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <line x1="3" y1="12" x2="21" y2="12"></line>
                <line x1="3" y1="6" x2="21" y2="6"></line>
                <line x1="3" y1="18" x2="21" y2="18"></line>
            </svg>
        </button>
        <?php endif; ?>

        <!-- IFRAME CENTRAL -->
        <iframe name="content-frame" id="app-frame" src="<?php echo htmlspecialchars($defaultFrameSrc, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?>"></iframe>
    </main>

</div>

<script>
    const dashboardCleanUrl = <?php echo json_encode(app_url('dashboard.php'), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); ?>;
    const dashboardInitialFrameSrc = <?php echo json_encode($defaultFrameSrc, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); ?>;
    const dashboardHasExplicitOpen = <?php echo $requestedFrameSrc !== '' ? 'true' : 'false'; ?>;
    const dashboardFrameStorageKey = 'dashboard:last-frame-src';
    const dashboardAllowedFrameSrcs = <?php echo json_encode(array_keys($allowedFrameSrcs), JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); ?>;
    const dashboardBaseDir = (function () {
        try {
            const url = new URL(dashboardCleanUrl, window.location.href);
            return url.pathname.replace(/[^/]+$/, '');
        } catch (e) {
            return '/';
        }
    })();

    function normalizeDashboardFrameSrc(src) {
        const value = String(src || '').trim();
        if (!value) {
            return '';
        }

        try {
            const url = new URL(value, window.location.href);
            if (url.origin !== window.location.origin) {
                return value;
            }
            let path = url.pathname || '';
            if (dashboardBaseDir !== '/' && path.startsWith(dashboardBaseDir)) {
                path = path.slice(dashboardBaseDir.length);
            } else {
                path = path.replace(/^\/+/, '');
            }
            return path + (url.search || '');
        } catch (e) {
            return value.replace(/^\/+/, '');
        }
    }

    function dashboardFrameDir(src) {
        const normalized = normalizeDashboardFrameSrc(src);
        if (!normalized) {
            return '';
        }

        const clean = normalized.split('?')[0];
        const slashPos = clean.lastIndexOf('/');
        if (slashPos < 0) {
            return '';
        }

        return clean.slice(0, slashPos + 1);
    }

    function rememberDashboardFrame(src) {
        const value = String(src || '').trim();
        if (!value) {
            return;
        }
        try {
            sessionStorage.setItem(dashboardFrameStorageKey, value);
        } catch (e) {
        }
    }

    function clearDashboardFrame() {
        try {
            sessionStorage.removeItem(dashboardFrameStorageKey);
        } catch (e) {
        }
    }

    function readRememberedDashboardFrame() {
        try {
            return sessionStorage.getItem(dashboardFrameStorageKey) || '';
        } catch (e) {
            return '';
        }
    }

    function isAllowedDashboardFrame(src) {
        const value = normalizeDashboardFrameSrc(src);
        if (!value) {
            return false;
        }

        for (const allowed of dashboardAllowedFrameSrcs) {
            if (value === allowed) {
                return true;
            }
            if (allowed !== 'wellcome_context.php' && value.startsWith(allowed + '?')) {
                return true;
            }
        }

        return false;
    }

    function findNavItemForFrameSrc(src) {
        const value = normalizeDashboardFrameSrc(src);
        if (!value) {
            return null;
        }

        let found = null;
        document.querySelectorAll('.nav-item').forEach(item => {
            if (found) {
                return;
            }

            const href = normalizeDashboardFrameSrc(item.getAttribute('href') || '');
            const appUrl = normalizeDashboardFrameSrc(item.getAttribute('data-app-url') || '');
            const valueDir = dashboardFrameDir(value);
            const hrefDir = dashboardFrameDir(href);
            const appUrlDir = dashboardFrameDir(appUrl);

            if (item.hasAttribute('data-dashboard-home')) {
                if (value === 'wellcome_context.php') {
                    found = item;
                }
                return;
            }

            if (href !== '' && href === value) {
                found = item;
                return;
            }

            if (appUrl !== '' && (value === appUrl || value.startsWith(appUrl + '?'))) {
                found = item;
                return;
            }

            if (valueDir !== '' && ((appUrlDir !== '' && valueDir === appUrlDir) || (hrefDir !== '' && valueDir === hrefDir))) {
                found = item;
            }
        });

        return found;
    }

    function getCurrentDashboardFrameSrc(appFrame) {
        if (!appFrame) {
            return '';
        }

        try {
            const currentHref = appFrame.contentWindow && appFrame.contentWindow.location
                ? appFrame.contentWindow.location.href
                : '';
            const normalized = normalizeDashboardFrameSrc(currentHref);
            if (normalized !== '') {
                return normalized;
            }
        } catch (e) {
        }

        return normalizeDashboardFrameSrc(appFrame.getAttribute('src') || '');
    }

    function setActive(element) {
        const items = document.querySelectorAll('.nav-item');
        items.forEach(item => item.classList.remove('active'));
        document.querySelectorAll('.launcher-menu-toggle').forEach(item => item.classList.remove('active'));
        element.classList.add('active');

        const panel = element.closest('.launcher-panel');
        if (panel) {
            const panelId = panel.getAttribute('data-launcher-panel-content') || '';
            const button = document.querySelector('[data-launcher-panel="' + panelId + '"]');
            if (button) {
                button.classList.add('active');
            }
        }

        const href = normalizeDashboardFrameSrc(element.getAttribute('href') || '');
        if (element.hasAttribute('data-dashboard-home')) {
            clearDashboardFrame();
        } else if (href !== '') {
            rememberDashboardFrame(href);
        }

        if (window.innerWidth <= 768) {
            const sidebar = document.querySelector('.sidebar');
            if (sidebar) {
                sidebar.classList.add('collapsed');
            }
        }
    }

    function closeLauncherPanels() {
        document.querySelectorAll('.launcher-panel.is-open').forEach(panel => {
            panel.classList.remove('is-open');
        });
        document.querySelectorAll('.launcher-menu-toggle[aria-expanded="true"]').forEach(btn => {
            btn.setAttribute('aria-expanded', 'false');
            btn.classList.remove('is-open');
        });
    }

    function toggleLauncherPanel(panelId) {
        const panel = document.querySelector('[data-launcher-panel-content="' + panelId + '"]');
        const button = document.querySelector('[data-launcher-panel="' + panelId + '"]');
        if (!panel || !button) {
            return;
        }

        const willOpen = !panel.classList.contains('is-open');
        closeLauncherPanels();
        if (willOpen) {
            panel.classList.add('is-open');
            button.classList.add('is-open');
            button.setAttribute('aria-expanded', 'true');
        }
    }

    function syncActiveNavByFrameSrc(src) {
        const found = findNavItemForFrameSrc(src);
        if (found) {
            setActive(found);
        }
    }

    function syncFrameHeaderBranding() {
        const appFrame = document.getElementById('app-frame');
        if (!appFrame || !appFrame.contentWindow || !appFrame.contentWindow.document) {
            return;
        }

        const activeItem = findNavItemForFrameSrc(getCurrentDashboardFrameSrc(appFrame))
            || document.querySelector('.nav-item.active:not([data-dashboard-home])');
        if (!activeItem) {
            return;
        }

        const frameDoc = appFrame.contentWindow.document;
        const headerInfo = (function () {
            const explicit = frameDoc.querySelector(
                '.header-top .header-titles, .header-top .header-info, header.header-intranet-top .header-left.header-info, header.header-intranet-top .header-left, header.header-intranet-top .header-info, .gf-header .gf-title'
            );
            if (explicit) {
                return explicit;
            }

            const plainHeader = frameDoc.querySelector('.header-top, header.header-intranet-top, .gf-header');
            if (plainHeader) {
                return Array.from(plainHeader.children).find(child => {
                    if (!(child instanceof appFrame.contentWindow.HTMLElement)) {
                        return false;
                    }
                    if (child.classList.contains('header-actions')) {
                        return false;
                    }
                    return !!child.querySelector('h1, h2, h3, h4, h5, p');
                }) || plainHeader;
            }

            return frameDoc.querySelector('body > .app-container > header:first-of-type, body > header:first-of-type');
        })();
        if (!headerInfo) {
            return;
        }

        const existingBrand = headerInfo.matches('.app-header-brand, .iban-header-brand, .gf-header-brand, .gf-title')
            ? headerInfo
            : headerInfo.querySelector('.app-header-brand, .iban-header-brand, .gf-header-brand, .gf-title');
        const titleEl = existingBrand
            ? existingBrand.querySelector('h1, h2, h3, h4, h5')
            : headerInfo.querySelector('h1, h2, h3, h4, h5');
        if (!titleEl) {
            return;
        }

        const iconSource = activeItem.querySelector('.nav-icon');
        if (!iconSource) {
            return;
        }

        const descriptionEl = existingBrand
            ? existingBrand.querySelector('p')
            : headerInfo.querySelector('p');
        const brand = frameDoc.createElement('div');
        brand.className = 'app-header-brand';

        const icon = frameDoc.createElement('div');
        icon.className = 'app-header-icon';
        icon.setAttribute('aria-hidden', 'true');
        icon.innerHTML = iconSource.innerHTML;

        const copy = frameDoc.createElement('div');
        copy.className = 'app-header-copy';
        copy.appendChild(titleEl);
        if (descriptionEl) {
            copy.appendChild(descriptionEl);
        }

        brand.appendChild(icon);
        brand.appendChild(copy);
        if (existingBrand && existingBrand.parentNode) {
            existingBrand.parentNode.replaceChild(brand, existingBrand);
        } else {
            headerInfo.prepend(brand);
        }
    }

    document.addEventListener("DOMContentLoaded", function () {
        const sidebar = document.querySelector('.sidebar');
        const toggleBtn = document.getElementById('sidebarToggle');
        const appFrame = document.getElementById('app-frame');

        const isCollapsed = localStorage.getItem('sidebar-collapsed') === 'true';
        const isMobile = window.innerWidth <= 768;

            if (dashboardHasExplicitOpen) {
            if (isAllowedDashboardFrame(dashboardInitialFrameSrc)) {
                const initialFrame = normalizeDashboardFrameSrc(dashboardInitialFrameSrc);
                rememberDashboardFrame(initialFrame);
                syncActiveNavByFrameSrc(initialFrame);
            } else {
                clearDashboardFrame();
                if (appFrame) {
                    appFrame.setAttribute('src', 'wellcome_context.php');
                }
            }
            if (window.location.pathname.toLowerCase().endsWith('/dashboard.php') || window.location.pathname.toLowerCase() === '/dashboard.php') {
                window.history.replaceState({}, document.title, dashboardCleanUrl);
            }
        } else if (appFrame) {
            let shouldRestoreRememberedFrame = false;
            try {
                const navEntry = performance.getEntriesByType && performance.getEntriesByType('navigation')[0];
                shouldRestoreRememberedFrame = !!navEntry && navEntry.type === 'reload';
            } catch (e) {
                shouldRestoreRememberedFrame = false;
            }

            const rememberedFrame = readRememberedDashboardFrame();
            if (shouldRestoreRememberedFrame && rememberedFrame !== '' && isAllowedDashboardFrame(rememberedFrame) && appFrame.getAttribute('src') === 'wellcome_context.php') {
                appFrame.setAttribute('src', rememberedFrame);
                syncActiveNavByFrameSrc(rememberedFrame);
            } else if (rememberedFrame !== '' && !isAllowedDashboardFrame(rememberedFrame)) {
                clearDashboardFrame();
            } else if (!shouldRestoreRememberedFrame) {
                clearDashboardFrame();
                appFrame.setAttribute('src', 'wellcome_context.php');
                syncActiveNavByFrameSrc('wellcome_context.php');
            }
        }

        if (sidebar && isCollapsed) {
            sidebar.classList.add('collapsed');
        } else if (sidebar && isMobile && localStorage.getItem('sidebar-collapsed') === null) {
            sidebar.classList.add('collapsed');
        }

        function promoteFrameToTopIfNeeded() {
            if (!appFrame) return;
            try {
                const frameUrl = new URL(appFrame.contentWindow.location.href, window.location.href);
                const path = (frameUrl.pathname || '').toLowerCase();
                const isLoginPage = /\/login\.php$/.test(path);
                const isExpired = frameUrl.searchParams.get('expired') === '1' || frameUrl.searchParams.get('session_expired') === '1';
                if (isLoginPage || isExpired) {
                    window.location.replace(frameUrl.href);
                }
            } catch (e) {
                // Si el navegador no permite inspeccionar el iframe, no forzamos nada.
            }
        }

        if (appFrame) {
            appFrame.addEventListener('load', function () {
                promoteFrameToTopIfNeeded();
                const currentSrc = getCurrentDashboardFrameSrc(appFrame);
                syncActiveNavByFrameSrc(currentSrc);
                syncFrameHeaderBranding();
                if (currentSrc === 'wellcome_context.php') {
                    clearDashboardFrame();
                } else if (currentSrc !== '') {
                    rememberDashboardFrame(currentSrc);
                }
            });
        }

        document.querySelectorAll('.nav-group').forEach(groupEl => {
            const gid = groupEl.getAttribute('data-group-id') || 'grupo';
            const key = 'nav-group-collapsed:' + gid;
            const collapsed = localStorage.getItem(key) === 'true';
            if (collapsed) groupEl.classList.add('is-collapsed');

            const btn = groupEl.querySelector('.nav-group-title-toggle');
            if (btn) {
                btn.setAttribute('aria-expanded', String(!collapsed));
                btn.addEventListener('click', () => {
                    groupEl.classList.toggle('is-collapsed');
                    const isCol = groupEl.classList.contains('is-collapsed');
                    btn.setAttribute('aria-expanded', String(!isCol));
                    localStorage.setItem(key, String(isCol));
                });
            }
        });

        if (toggleBtn) {
            toggleBtn.addEventListener('click', function () {
                if (!sidebar) {
                    return;
                }
                sidebar.classList.toggle('collapsed');
                const currentState = sidebar.classList.contains('collapsed');
                localStorage.setItem('sidebar-collapsed', currentState);
            });
        }

        document.querySelectorAll('.launcher-menu-toggle').forEach(btn => {
            btn.addEventListener('click', function () {
                toggleLauncherPanel(this.getAttribute('data-launcher-panel') || '');
            });
        });

        document.querySelectorAll('.launcher-panel-close').forEach(btn => {
            btn.addEventListener('click', closeLauncherPanels);
        });

        document.addEventListener('keydown', function (event) {
            if (event.key === 'Escape') {
                closeLauncherPanels();
            }
        });

        document.addEventListener('click', function (event) {
            if (!event.target.closest('.dashboard-launcher') && !event.target.closest('.launcher-panel')) {
                closeLauncherPanels();
            }
        });
    });
</script>

</body>
</html>
