<?php
/**
 * @intranet-file wellcome_context.php
 * @intranet-file-version 2026.05.05.1
 * @intranet-file-date 2026-05-05
 * @intranet-file-owner CSIF Intranet
 */
ini_set('session.gc_maxlifetime', '3600');
session_start();

require_once __DIR__ . '/common/config.php';
require_once __DIR__ . '/common/url.php';
require_once __DIR__ . '/common/user_preferences.php';
require_once __DIR__ . '/common/catalogo_db.php';
require_once __DIR__ . '/common/plugin_store.php';
require_once __DIR__ . '/common/visitas_tracking.php';

function welcome_asset_src(string $src): string
{
    $src = trim($src);
    if ($src === '' || preg_match('~^(?:https?:)?//~i', $src)) {
        return $src;
    }

    return asset_url(ltrim($src, '/'));
}

function welcome_first_letter(string $text): string
{
    $text = trim($text);
    if ($text === '') {
        return '?';
    }

    if (function_exists('mb_substr')) {
        return mb_strtoupper(mb_substr($text, 0, 1, 'UTF-8'), 'UTF-8');
    }

    return strtoupper(substr($text, 0, 1));
}

function welcome_short_text(string $text, int $max = 20): string
{
    $text = trim(preg_replace('/\s+/u', ' ', $text) ?? $text);
    if ($text === '') {
        return '';
    }

    if (function_exists('mb_strlen') && function_exists('mb_substr')) {
        if (mb_strlen($text, 'UTF-8') <= $max) {
            return $text;
        }

        return rtrim(mb_substr($text, 0, $max, 'UTF-8')) . '...';
    }

    if (strlen($text) <= $max) {
        return $text;
    }

    return rtrim(substr($text, 0, $max)) . '...';
}

function welcome_plugin_store_plugins(array $store): array
{
    $list = $store['plugins'] ?? $store;
    if (!is_array($list)) {
        return [];
    }

    $plugins = [];
    foreach ($list as $item) {
        if (!is_array($item)) {
            continue;
        }
        $id = trim((string) ($item['id'] ?? ''));
        if ($id === '') {
            continue;
        }
        $plugins[$id] = $item;
    }
    return $plugins;
}

function welcome_plugin_roles($value): array
{
    if (is_array($value)) {
        $roles = [];
        foreach ($value as $role) {
            $role = trim((string) $role);
            if ($role !== '') {
                $roles[] = $role;
            }
        }
        return array_values(array_unique($roles));
    }

    return catalogo_roles_from_json(is_string($value) ? $value : '');
}

function welcome_plugin_default_group(array $plugin): string
{
    $candidates = [
        $plugin['default_group_name'] ?? '',
        $plugin['group_name'] ?? '',
        $plugin['app']['default_group_name'] ?? '',
        $plugin['app']['group_name'] ?? '',
    ];

    foreach ($candidates as $candidate) {
        $group = trim((string) $candidate);
        if ($group !== '') {
            return catalogo_normalize_app_group_name($group);
        }
    }

    return 'Mis apps';
}

function welcome_plugin_required_roles(array $plugin): array
{
    foreach ([
        $plugin['roles_json'] ?? null,
        $plugin['app']['roles_json'] ?? null,
        $plugin['roles'] ?? null,
    ] as $candidate) {
        $roles = welcome_plugin_roles($candidate);
        if ($roles !== []) {
            return $roles;
        }
    }

    return [];
}

function welcome_plugin_is_admin_only(array $plugin): bool
{
    $groupKey = catalogo_app_group_key(welcome_plugin_default_group($plugin));
    if ($groupKey === 'administracion') {
        return true;
    }

    $roles = array_map('strtolower', welcome_plugin_required_roles($plugin));
    if ($roles === []) {
        return false;
    }

    $nonAdminRoles = array_values(array_filter($roles, static function (string $role): bool {
        return !in_array($role, ['administradores', 'admin', 'admins'], true);
    }));

    return $nonAdminRoles === [];
}

function welcome_version_is_newer(string $candidate, string $current): bool
{
    $candidate = trim($candidate);
    $current = trim($current);
    if ($candidate === '') {
        return false;
    }
    if ($current === '') {
        return true;
    }
    return version_compare($candidate, $current, '>');
}

function welcome_local_plugin_version(string $pluginId): string
{
    $pluginId = trim($pluginId);
    if ($pluginId === '' || preg_match('~[^A-Za-z0-9._-]~', $pluginId)) {
        return '';
    }

    $path = __DIR__ . '/plugins/' . $pluginId . '/plugin.json';
    if (!is_file($path)) {
        return '';
    }

    $data = json_decode((string) @file_get_contents($path), true);
    return is_array($data) ? trim((string) ($data['version'] ?? '')) : '';
}

function welcome_pending_core_updates(array $store, array $localUpdates, string $currentVersion): array
{
    $items = [];
    $seen = [];
    $remote = $store['core_updates'] ?? [];
    if (is_array($remote)) {
        foreach ($remote as $item) {
            if (!is_array($item)) {
                continue;
            }
            $version = trim((string) ($item['version'] ?? ''));
            if (!welcome_version_is_newer($version, $currentVersion)) {
                continue;
            }
            $key = 'remote:' . ((string) ($item['id'] ?? $version));
            if (isset($seen[$key])) {
                continue;
            }
            $seen[$key] = true;
            $items[] = [
                'name' => (string) ($item['name'] ?? 'Actualizacion del nucleo'),
                'version' => $version,
                'description' => (string) ($item['description'] ?? ''),
                'source' => 'Store',
            ];
        }
    }

    foreach ($localUpdates as $item) {
        if (!is_array($item)) {
            continue;
        }
        $version = trim((string) ($item['version'] ?? ''));
        if (!welcome_version_is_newer($version, $currentVersion)) {
            continue;
        }
        $key = 'local:' . ((string) ($item['_file'] ?? $version));
        if (isset($seen[$key])) {
            continue;
        }
        $seen[$key] = true;
        $items[] = [
            'name' => (string) ($item['name'] ?? 'Actualizacion del nucleo'),
            'version' => $version,
            'description' => (string) ($item['description'] ?? ''),
            'source' => 'Paquete local',
        ];
    }

    usort($items, static function (array $a, array $b): int {
        return version_compare((string) ($b['version'] ?? ''), (string) ($a['version'] ?? ''));
    });

    return $items;
}

function welcome_home_alerts(PDO $pdo, array $userRolesLower): array
{
    $isAdmin = in_array('administradores', $userRolesLower, true);
    $cacheKey = 'welcome_home_alerts_v1_' . md5(json_encode($userRolesLower));
    $cached = $_SESSION[$cacheKey] ?? null;
    if (is_array($cached) && (int) ($cached['expires_at'] ?? 0) > time()) {
        return is_array($cached['data'] ?? null) ? $cached['data'] : [];
    }

    $data = [
        'admin_install' => [],
        'admin_update' => [],
        'admin_core' => [],
        'user_plugins' => [],
        'errors' => [],
    ];

    $errors = [];
    try {
        $store = plugin_store_fetch_index($errors);
        if (!is_array($store)) {
            $data['errors'] = $errors;
            $_SESSION[$cacheKey] = [
                'expires_at' => time() + 180,
                'data' => $data,
            ];
            return $data;
        }

        $installed = plugin_installed_all($pdo);
        foreach (welcome_plugin_store_plugins($store) as $id => $plugin) {
            $name = (string) ($plugin['name'] ?? $id);
            $description = (string) ($plugin['description'] ?? '');
            $storeVersion = trim((string) ($plugin['version'] ?? ''));
            $installedRow = $installed[$id] ?? null;
            $installedVersion = is_array($installedRow) ? trim((string) ($installedRow['version'] ?? '')) : '';
            $localVersion = is_array($installedRow) ? welcome_local_plugin_version($id) : '';
            $currentVersion = $localVersion !== '' ? $localVersion : $installedVersion;

            if ($isAdmin) {
                if (!is_array($installedRow)) {
                    $data['admin_install'][] = [
                        'id' => $id,
                        'name' => $name,
                        'version' => $storeVersion,
                        'description' => $description,
                    ];
                    continue;
                }

                if ($storeVersion !== '' && ($currentVersion === '' || version_compare($storeVersion, $currentVersion, '>'))) {
                    $data['admin_update'][] = [
                        'id' => $id,
                        'name' => $name,
                        'version' => $storeVersion,
                        'current_version' => $currentVersion,
                        'description' => $description,
                    ];
                }
                continue;
            }

            if (is_array($installedRow) || welcome_plugin_is_admin_only($plugin)) {
                continue;
            }

            $requiredRoles = welcome_plugin_required_roles($plugin);
            if ($requiredRoles !== [] && !catalogo_roles_allow($userRolesLower, $requiredRoles)) {
                continue;
            }

            $data['user_plugins'][] = [
                'id' => $id,
                'name' => $name,
                'version' => $storeVersion,
                'description' => $description,
                'group' => welcome_plugin_default_group($plugin),
            ];
        }

        if ($isAdmin) {
            $localUpdateErrors = [];
            $data['admin_core'] = welcome_pending_core_updates(
                $store,
                core_update_list_local_packages($localUpdateErrors),
                core_update_current_version()
            );
            $errors = array_merge($errors, $localUpdateErrors);
        }

        $data['errors'] = $errors;
    } catch (Throwable $e) {
        $data['errors'][] = $e->getMessage();
    }

    $_SESSION[$cacheKey] = [
        'expires_at' => time() + 180,
        'data' => $data,
    ];

    return $data;
}

function welcome_frequent_icon_markup(array $item): string
{
    $svg = catalogo_normalize_svg_markup($item['icon_svg'] ?? null);
    if ($svg !== null) {
        return '<span class="welcome-frequent-icon-svg" aria-hidden="true">' . $svg . '</span>';
    }

    $image = trim((string) ($item['image'] ?? ''));
    if ($image !== '') {
        return '<img src="' . h(welcome_asset_src(catalogo_image_src($image))) . '" alt="">';
    }

    return '<span class="welcome-frequent-letter">' . h(welcome_first_letter((string) ($item['label'] ?? ''))) . '</span>';
}

function welcome_frequent_items(PDO $pdo, string $username, array $userRolesLower, int $limit): array
{
    $limit = intranet_home_frequent_limit_normalize($limit);
    if ($limit <= 0 || trim($username) === '') {
        return [];
    }

    visitas_ensure_schema($pdo);

    $appsById = [];
    foreach (catalogo_apps_fetch($pdo, true) as $row) {
        $appId = trim((string) ($row['app_id'] ?? ''));
        if ($appId === '') {
            continue;
        }
        $requiredRoles = catalogo_roles_from_json($row['roles_json'] ?? '');
        if (!catalogo_roles_allow($userRolesLower, $requiredRoles)) {
            continue;
        }

        $url = trim((string) ($row['url'] ?? ''));
        $appsById[$appId] = [
            'kind' => 'app',
            'id' => $appId,
            'label' => (string) ($row['name'] ?? $appId),
            'description' => (string) ($row['description'] ?? ''),
            'href' => 'go.php?app_id=' . rawurlencode($appId),
            'target' => (!empty($row['new_tab']) || preg_match('~^https?://~i', $url)) ? '_blank' : '_self',
            'icon_svg' => $row['icon'] ?? '',
            'image' => $row['image'] ?? '',
            'type_label' => 'Aplicacion',
        ];
    }

    $linkTypeLabels = [
        'links' => 'Enlace',
        'nntt' => 'NNTT',
        'novedades' => 'Novedad',
    ];
    $linksByKey = [];
    foreach ($linkTypeLabels as $type => $typeLabel) {
        foreach (catalogo_links_fetch($pdo, $type, true) as $row) {
            $linkId = (int) ($row['id'] ?? 0);
            if ($linkId <= 0) {
                continue;
            }
            $groupName = trim((string) ($row['grupo'] ?? ''));
            $linksByKey[$type . ':' . $linkId] = [
                'kind' => 'link',
                'id' => (string) $linkId,
                'label' => (string) ($row['descripcion'] ?? ('Enlace #' . $linkId)),
                'description' => $groupName !== '' ? $groupName : $typeLabel,
                'href' => 'go.php?link_id=' . $linkId,
                'target' => '_blank',
                'icon_svg' => $row['icon_svg'] ?? '',
                'image' => $row['imagen'] ?? '',
                'type_label' => $typeLabel,
            ];
        }
    }

    $scanLimit = min(200, max($limit * 8, $limit));
    $st = $pdo->prepare(
        "SELECT item_kind, item_key, COALESCE(link_type, '') AS link_type,
                COUNT(*) AS total, MAX(created_at) AS last_click_at
           FROM stats_clicks
          WHERE username = :username
            AND item_kind IN ('app', 'link')
          GROUP BY item_kind, item_key, link_type
          ORDER BY total DESC, last_click_at DESC
          LIMIT :scan_limit"
    );
    $st->bindValue(':username', $username, PDO::PARAM_STR);
    $st->bindValue(':scan_limit', $scanLimit, PDO::PARAM_INT);
    $st->execute();

    $items = [];
    foreach ($st->fetchAll(PDO::FETCH_ASSOC) ?: [] as $row) {
        $kind = (string) ($row['item_kind'] ?? '');
        $base = null;
        if ($kind === 'app') {
            $base = $appsById[(string) ($row['item_key'] ?? '')] ?? null;
        } elseif ($kind === 'link') {
            $base = $linksByKey[(string) ($row['link_type'] ?? '') . ':' . (int) ($row['item_key'] ?? 0)] ?? null;
        }
        if ($base === null) {
            continue;
        }

        $base['total'] = (int) ($row['total'] ?? 0);
        $base['last_click_at'] = (string) ($row['last_click_at'] ?? '');
        $items[] = $base;
        if (count($items) >= $limit) {
            break;
        }
    }

    return $items;
}

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

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

$pdo = db();
$themeMode = intranet_load_session_theme_mode($pdo);
$homeFrequentLimit = intranet_load_session_home_frequent_limit($pdo);
$homeFrequentAppBg = intranet_load_session_home_frequent_app_bg($pdo);
$homeFrequentLinkBg = intranet_load_session_home_frequent_link_bg($pdo);
$homeFrequentAppText = intranet_hex_contrast_text($homeFrequentAppBg);
$homeFrequentLinkText = intranet_hex_contrast_text($homeFrequentLinkBg);

$nombre = $_SESSION['givenName'] ?? '';
$username = (string) ($_SESSION['username'] ?? '');
$primaryRole = $_SESSION['primaryRole'] ?? '';
$allRoles = is_array($_SESSION['roles'] ?? null) ? $_SESSION['roles'] : [];
$userRolesLower = array_map('strtolower', array_map('strval', $allRoles));
$isAdminUser = in_array('administradores', $userRolesLower, true);
$homeAlerts = welcome_home_alerts($pdo, $userRolesLower);
$frequentItems = [];
if ($homeFrequentLimit > 0) {
    try {
        $frequentItems = welcome_frequent_items($pdo, $username, $userRolesLower, $homeFrequentLimit);
    } catch (Throwable $e) {
        $frequentItems = [];
    }
}

if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
    $ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0];
} else {
    $ip = $_SERVER['REMOTE_ADDR'] ?? '';
}

$displayRole = str_replace(['app_', 'administradores'], ['', 'Administrador'], $primaryRole);
$welcomeEntity = defined('INTRANET_WELCOME_ENTITY') ? INTRANET_WELCOME_ENTITY : 'la organizacion';
$styleVersion = (string) (@filemtime(__DIR__ . '/styles/css/style.css') ?: time());
$themeVarsVersion = (string) (@filemtime(__DIR__ . '/styles/css/theme-vars.css') ?: time());
?>
<!DOCTYPE html>
<html lang="es" <?= intranet_theme_html_attr($themeMode); ?>>
<head>
    <meta charset="UTF-8">
    <title>Bienvenido</title>
    <?= intranet_theme_bootstrap_script_tag($themeMode); ?>
    <link rel="stylesheet" href="<?= h(asset_url('styles/css/style.css')) ?>?v=<?= h($styleVersion) ?>">
    <link rel="stylesheet" href="<?= h(asset_url('styles/css/theme-vars.css')) ?>?v=<?= h($themeVarsVersion) ?>">
</head>
<body class="welcome-body">
    <div class="welcome-card" style="--home-frequent-app-bg: <?= h($homeFrequentAppBg) ?>; --home-frequent-link-bg: <?= h($homeFrequentLinkBg) ?>; --home-frequent-app-text: <?= h($homeFrequentAppText) ?>; --home-frequent-link-text: <?= h($homeFrequentLinkText) ?>;">
        <h1 class="welcome-title">Hola, <?= h($nombre) ?></h1>
        <p class="welcome-subtitle">Bienvenido al Portal Corporativo de <?= h($welcomeEntity) ?>.</p>

        <div class="stats-grid">
            <div class="stat-box">
                <span class="stat-label">Perfil Principal</span>
                <span class="stat-value highlight" style="text-transform: capitalize;">
                    <?= h($displayRole) ?>
                </span>
            </div>
            <div class="stat-box">
                <span class="stat-label">Grupos Detectados</span>
                <span class="stat-value" style="font-size: 0.9rem;">
                    <?php
                    $cleanRoles = array_map(static function ($r) {
                        return ucfirst(str_replace('app_', '', (string) $r));
                    }, $allRoles);
                    echo h(implode(', ', $cleanRoles));
                    ?>
                </span>
            </div>
            <div class="stat-box">
                <span class="stat-label">Direccion IP</span>
                <span class="stat-value" style="font-family: monospace;"><?= h((string) $ip) ?></span>
            </div>
        </div>

        <?php if (in_array('administradores', $allRoles, true)): ?>
            <div class="admin-notice">
                <h4>Panel de Administracion</h4>
                <p>Tienes acceso total al sistema.</p>
            </div>
        <?php endif; ?>

        <?php
        $adminInstall = is_array($homeAlerts['admin_install'] ?? null) ? $homeAlerts['admin_install'] : [];
        $adminUpdate = is_array($homeAlerts['admin_update'] ?? null) ? $homeAlerts['admin_update'] : [];
        $adminCore = is_array($homeAlerts['admin_core'] ?? null) ? $homeAlerts['admin_core'] : [];
        $userPlugins = is_array($homeAlerts['user_plugins'] ?? null) ? $homeAlerts['user_plugins'] : [];
        $hasAdminPending = $isAdminUser && ($adminInstall !== [] || $adminUpdate !== [] || $adminCore !== []);
        ?>

        <?php if ($hasAdminPending): ?>
            <section class="welcome-update-alert welcome-update-alert--admin" aria-label="Actualizaciones pendientes">
                <div class="welcome-update-alert-head">
                    <div>
                        <h2>Hay mantenimiento pendiente</h2>
                        <p>Revisa plugins y actualizaciones del nucleo disponibles para esta intranet.</p>
                    </div>
                    <div class="welcome-update-actions">
                        <?php if ($adminInstall !== [] || $adminUpdate !== []): ?>
                            <a href="<?= h(asset_url('dashboard.php') . '?open=' . rawurlencode('base/plugins/index.php')) ?>" target="_top">Gestionar plugins</a>
                        <?php endif; ?>
                        <?php if ($adminCore !== []): ?>
                            <a href="<?= h(asset_url('dashboard.php') . '?open=' . rawurlencode('base/updates/index.php')) ?>" target="_top">Ver nucleo</a>
                        <?php endif; ?>
                    </div>
                </div>

                <div class="welcome-update-summary">
                    <?php if ($adminUpdate !== []): ?>
                        <span><?= count($adminUpdate) ?> plugin(s) para actualizar</span>
                    <?php endif; ?>
                    <?php if ($adminInstall !== []): ?>
                        <span><?= count($adminInstall) ?> plugin(s) para instalar</span>
                    <?php endif; ?>
                    <?php if ($adminCore !== []): ?>
                        <span><?= count($adminCore) ?> actualizacion(es) del nucleo</span>
                    <?php endif; ?>
                </div>

                <div class="welcome-update-list">
                    <?php foreach (array_slice($adminUpdate, 0, 4) as $plugin): ?>
                        <article>
                            <strong><?= h((string) ($plugin['name'] ?? 'Plugin')) ?></strong>
                            <span>Actualizar <?= h((string) ($plugin['current_version'] ?? '-')) ?> a <?= h((string) ($plugin['version'] ?? '-')) ?></span>
                        </article>
                    <?php endforeach; ?>
                    <?php foreach (array_slice($adminInstall, 0, 4) as $plugin): ?>
                        <article>
                            <strong><?= h((string) ($plugin['name'] ?? 'Plugin')) ?></strong>
                            <span>Instalar<?= trim((string) ($plugin['version'] ?? '')) !== '' ? ' version ' . h((string) $plugin['version']) : '' ?></span>
                        </article>
                    <?php endforeach; ?>
                    <?php foreach (array_slice($adminCore, 0, 3) as $update): ?>
                        <article>
                            <strong><?= h((string) ($update['name'] ?? 'Actualizacion del nucleo')) ?></strong>
                            <span><?= h((string) ($update['source'] ?? '')) ?> - version <?= h((string) ($update['version'] ?? '-')) ?></span>
                        </article>
                    <?php endforeach; ?>
                </div>
            </section>
        <?php elseif (!$isAdminUser && $userPlugins !== []): ?>
            <section class="welcome-update-alert welcome-update-alert--user" aria-label="Plugins nuevos disponibles">
                <div class="welcome-update-alert-head">
                    <div>
                        <h2>Nuevas herramientas disponibles</h2>
                        <p>Estos plugins no administrativos estan publicados en el Store.</p>
                    </div>
                </div>
                <div class="welcome-update-list">
                    <?php foreach (array_slice($userPlugins, 0, 6) as $plugin): ?>
                        <article>
                            <strong><?= h((string) ($plugin['name'] ?? 'Plugin')) ?></strong>
                            <span><?= h((string) (($plugin['description'] ?? '') !== '' ? $plugin['description'] : 'Nueva herramienta disponible para la intranet.')) ?></span>
                        </article>
                    <?php endforeach; ?>
                </div>
            </section>
        <?php endif; ?>

        <?php if ($homeFrequentLimit > 0): ?>
            <section class="welcome-frequent-section">
                <div class="welcome-section-heading">
                    <div>
                        <h2>Tus accesos frecuentes</h2>
                        <p>Aplicaciones y enlaces que mas utilizas desde la intranet.</p>
                    </div>
                    <a href="<?= h(asset_url('base/preferences/index.php')) ?>" class="welcome-section-link">Configurar</a>
                </div>

                <?php if (empty($frequentItems)): ?>
                    <div class="welcome-empty-state">
                        Todavia no hay accesos suficientes para calcular tus favoritos. Se iran mostrando cuando uses aplicaciones y enlaces desde la intranet.
                    </div>
                <?php else: ?>
                    <div class="welcome-frequent-grid">
                        <?php foreach ($frequentItems as $item): ?>
                            <?php
                            $kind = (string) ($item['kind'] ?? 'link');
                            $fullLabel = trim((string) ($item['label'] ?? 'Acceso'));
                            $fullDescription = trim((string) ($item['description'] ?? ''));
                            $shortLabel = welcome_short_text($fullLabel, 20);
                            $tooltip = $fullDescription !== '' ? $fullDescription : $fullLabel;
                            ?>
                            <a
                                href="<?= h((string) ($item['href'] ?? '#')) ?>"
                                target="<?= h((string) ($item['target'] ?? '_self')) ?>"
                                class="welcome-frequent-card is-<?= h($kind === 'app' ? 'app' : 'link') ?>"
                                title="<?= h($tooltip) ?>"
                                aria-label="<?= h($tooltip) ?>"
                            >
                                <span class="welcome-frequent-icon">
                                    <?= welcome_frequent_icon_markup($item) ?>
                                </span>
                                <span class="welcome-frequent-copy">
                                    <strong><?= h($shortLabel) ?></strong>
                                </span>
                            </a>
                        <?php endforeach; ?>
                    </div>
                <?php endif; ?>
            </section>
        <?php endif; ?>
    </div>
</body>
</html>
