<?php
/**
 * @intranet-file go.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();
}
if (!isset($_SESSION['username'])) {
    header('Location: ' . login_url());
    exit();
}

require_once __DIR__ . '/common/db.php';
require_once __DIR__ . '/common/catalogo_db.php';
require_once __DIR__ . '/common/visitas_tracking.php';



function normalize_internal_redirect_url(string $url): string
{
    $url = trim($url);
    if ($url === '') {
        return app_url('wellcome_context.php');
    }

    if (preg_match('~^(?:https?:)?//~i', $url) || strpos($url, 'mailto:') === 0 || strpos($url, 'tel:') === 0) {
        return $url;
    }

    if ($url[0] === '/') {
        return app_url(ltrim($url, '/'));
    }

    return app_url($url);
}

$username = (string)$_SESSION['username'];

$appId = $_GET['app_id'] ?? '';
$appId = is_string($appId) ? trim($appId) : '';

$linkId = $_GET['link_id'] ?? '';
$linkId = is_string($linkId) ? trim($linkId) : '';

// Modo tolerante:
// - Si viene link_id, se prioriza link (aunque también venga app_id)
// - Si no viene link_id, se intenta app
$hasLink = ($linkId !== '');
$hasApp  = (!$hasLink && $appId !== '');
if (!$hasLink && !$hasApp) {
    http_response_code(400);
    echo "Parámetros inválidos";
    exit();
}

// Buscar destino y registrar el clic
$userRoles = $_SESSION['roles'] ?? [];
$userRolesLower = array_map('strtolower', is_array($userRoles) ? $userRoles : []);

try {
    $pdo = db();

    if ($hasApp) {
        if (!preg_match('/^[a-zA-Z0-9_-]{1,100}$/', $appId)) {
            http_response_code(400);
            echo "app_id inválido";
            exit();
        }

        $row = catalogo_app_get($pdo, $appId);
        if (!$row || empty($row['url']) || empty($row['is_enabled'])) {
            http_response_code(404);
            echo "App no encontrada";
            exit();
        }

        $requiredRoles = catalogo_roles_from_json($row['roles_json'] ?? '');
        if (!catalogo_roles_allow($userRolesLower, $requiredRoles)) {
            http_response_code(403);
            echo "Acceso denegado";
            exit();
        }

        $url = normalize_internal_redirect_url((string)$row['url']);
        $label = (string)($row['name'] ?? $appId);

        // Guardar métricas (si falla, no bloquea)
        try {
            visitas_record_app_click($pdo, $username, $appId, $label, $url);
        } catch (Throwable $e) {
            // error_log($e->getMessage());
        }

        header("Location: " . $url, true, 302);
        exit();
    }

    // Link
    if (!ctype_digit($linkId)) {
        http_response_code(400);
        echo "link_id inválido";
        exit();
    }
    $lid = (int)$linkId;

    $st = $pdo->prepare(
        "SELECT id, link_type, descripcion, destino, is_enabled
         FROM intranet_links
         WHERE id = :id
         LIMIT 1"
    );
    $st->execute(['id' => $lid]);
    $row = $st->fetch(PDO::FETCH_ASSOC);
    if (!$row || empty($row['destino']) || empty($row['is_enabled'])) {
        http_response_code(404);
        echo "Enlace no encontrado";
        exit();
    }

    $url = normalize_internal_redirect_url((string)$row['destino']);
    $label = (string)($row['descripcion'] ?? ('link #' . $lid));
    $type = (string)($row['link_type'] ?? 'links');

    // Guardar métricas (si falla, no bloquea)
    try {
        visitas_record_link_click($pdo, $username, $lid, $type, $label, $url);
    } catch (Throwable $e) {
        // error_log($e->getMessage());
    }

    header("Location: " . $url, true, 302);
    exit();

} catch (Throwable $e) {
    http_response_code(500);
    echo "Error interno";
    exit();
}
