<?php
// concurso_nobel/includes/menu_concurso.php
// Motor de menú dinámico NOBEX usando ingreso por código.
// No cambia el login: lee permisos desde concurso_accesos y opciones desde concurso_menu.

declare(strict_types=1);

if (!function_exists('cn_menu_h')) {
    function cn_menu_h($valor): string
    {
        return htmlspecialchars((string)$valor, ENT_QUOTES, 'UTF-8');
    }
}

if (!function_exists('cn_menu_color_seguro')) {
    function cn_menu_color_seguro($color): string
    {
        $color = trim((string)$color);

        // Por seguridad, en estilos inline solo aceptamos HEX.
        if (preg_match('/^#[0-9a-fA-F]{3}$/', $color) === 1 || preg_match('/^#[0-9a-fA-F]{6}$/', $color) === 1) {
            return $color;
        }

        return '#facc15';
    }
}

if (!function_exists('cn_menu_tabla_tiene_columna')) {
    function cn_menu_tabla_tiene_columna(mysqli $conn, string $tabla, string $columna): bool
    {
        $tablaEsc = mysqli_real_escape_string($conn, $tabla);
        $colEsc = mysqli_real_escape_string($conn, $columna);

        $res = @mysqli_query($conn, "SHOW COLUMNS FROM `{$tablaEsc}` LIKE '{$colEsc}'");

        if (!$res) {
            return false;
        }

        $existe = mysqli_num_rows($res) > 0;
        mysqli_free_result($res);

        return $existe;
    }
}

if (!function_exists('cn_menu_es_admin_global')) {
    function cn_menu_es_admin_global(array $acceso): bool
    {
        $tipo = strtoupper(trim((string)($acceso['tipo_acceso'] ?? '')));
        $idConcurso = $acceso['id_concurso'] ?? null;
        $puedeAdministrar = (int)($acceso['puede_administrar'] ?? 0);

        return $tipo === 'ADMIN_GLOBAL'
            || ($puedeAdministrar === 1 && ($idConcurso === null || (int)$idConcurso === 0));
    }
}

if (!function_exists('cn_menu_es_admin')) {
    function cn_menu_es_admin(array $acceso): bool
    {
        return (int)($acceso['puede_administrar'] ?? 0) === 1 || cn_menu_es_admin_global($acceso);
    }
}

if (!function_exists('cn_menu_tiene_permiso')) {
    function cn_menu_tiene_permiso(array $acceso, string $permiso): bool
    {
        $permiso = strtoupper(trim($permiso));

        if ($permiso === '' || $permiso === 'NINGUNO') {
            return true;
        }

        if (cn_menu_es_admin($acceso)) {
            return true;
        }

        if ($permiso === 'REGISTRAR_PARTICIPANTES') {
            return (int)($acceso['puede_registrar_participantes'] ?? 0) === 1;
        }

        if ($permiso === 'REGISTRAR_RESULTADOS') {
            return (int)($acceso['puede_registrar_resultados'] ?? 0) === 1;
        }

        if ($permiso === 'VER_RESULTADOS') {
            return (int)($acceso['puede_ver_resultados'] ?? 0) === 1;
        }

        if ($permiso === 'ADMINISTRAR') {
            return (int)($acceso['puede_administrar'] ?? 0) === 1;
        }

        return false;
    }
}

if (!function_exists('cn_menu_es_acceso_salon')) {
    function cn_menu_es_acceso_salon(array $acceso): bool
    {
        return (int)($acceso['id_salon'] ?? 0) > 0 && !cn_menu_es_admin($acceso);
    }
}

if (!function_exists('cn_menu_ocultar_para_acceso')) {
    function cn_menu_ocultar_para_acceso(array $acceso, array $item): bool
    {
        if (!cn_menu_es_acceso_salon($acceso)) {
            return false;
        }

        $url = strtolower(trim((string)($item['url'] ?? '')));
        $urlLimpia = strtok($url, '?') ?: $url;

        return basename($urlLimpia) === 'participantes.php';
    }
}

if (!function_exists('cn_menu_prefijo_relativo')) {
    function cn_menu_prefijo_relativo(): string
    {
        $script = str_replace('\\', '/', (string)($_SERVER['SCRIPT_NAME'] ?? $_SERVER['PHP_SELF'] ?? ''));

        if (strpos($script, '/admin/') !== false || strpos($script, '/omr/') !== false) {
            return '../';
        }

        return '';
    }
}

if (!function_exists('cn_menu_es_url_absoluta')) {
    function cn_menu_es_url_absoluta(string $url): bool
    {
        return preg_match('#^(https?:)?//#i', $url) === 1
            || strpos($url, '/') === 0
            || strpos($url, 'mailto:') === 0
            || strpos($url, 'javascript:') === 0
            || strpos($url, '#') === 0;
    }
}

if (!function_exists('cn_menu_con_id_concurso')) {
    function cn_menu_con_id_concurso(string $url, int $idConcurso, bool $requiereConcurso): string
    {
        if (!$requiereConcurso || $idConcurso <= 0 || $url === '' || $url === '#') {
            return $url;
        }

        if (strpos($url, 'id_concurso=') !== false) {
            return $url;
        }

        $separador = strpos($url, '?') === false ? '?' : '&';
        return $url . $separador . 'id_concurso=' . urlencode((string)$idConcurso);
    }
}

if (!function_exists('cn_menu_normalizar_href')) {
    function cn_menu_normalizar_href(?string $url, int $idConcurso, bool $requiereConcurso): string
    {
        $url = trim((string)$url);

        if ($url === '') {
            return '#';
        }

        $url = cn_menu_con_id_concurso($url, $idConcurso, $requiereConcurso);

        if (cn_menu_es_url_absoluta($url)) {
            return $url;
        }

        return cn_menu_prefijo_relativo() . ltrim($url, '/');
    }
}

if (!function_exists('cn_menu_cargar')) {
    function cn_menu_cargar(mysqli $conn, array $acceso, int $idConcursoTrabajo = 0): array
    {
        $selectColor = cn_menu_tabla_tiene_columna($conn, 'concurso_menu', 'color_menu')
            ? 'color_menu,'
            : "'#facc15' AS color_menu,";

        $sql = "
            SELECT
                id_menu,
                parent_id,
                titulo,
                icono,
                {$selectColor}
                url,
                modulo,
                permiso_requerido,
                requiere_concurso,
                requiere_salon,
                solo_admin_global,
                orden,
                activo
            FROM concurso_menu
            WHERE activo = 1
            ORDER BY
                CASE WHEN parent_id IS NULL THEN id_menu ELSE parent_id END ASC,
                CASE WHEN parent_id IS NULL THEN 0 ELSE 1 END ASC,
                orden ASC,
                id_menu ASC
        ";

        $res = @mysqli_query($conn, $sql);

        if (!$res) {
            return [];
        }

        $permitidos = [];
        $idSalonAcceso = (int)($acceso['id_salon'] ?? 0);

        while ($row = mysqli_fetch_assoc($res)) {
            $permiso = (string)($row['permiso_requerido'] ?? 'NINGUNO');
            $requiereConcurso = (int)($row['requiere_concurso'] ?? 0) === 1;
            $requiereSalon = (int)($row['requiere_salon'] ?? 0) === 1;
            $soloAdminGlobal = (int)($row['solo_admin_global'] ?? 0) === 1;

            if ($soloAdminGlobal && !cn_menu_es_admin_global($acceso)) {
                continue;
            }

            if ($requiereConcurso && $idConcursoTrabajo <= 0) {
                continue;
            }

            if ($requiereSalon && $idSalonAcceso <= 0) {
                continue;
            }

            if (!cn_menu_tiene_permiso($acceso, $permiso)) {
                continue;
            }

            if (cn_menu_ocultar_para_acceso($acceso, $row)) {
                continue;
            }

            $row['color_menu'] = cn_menu_color_seguro($row['color_menu'] ?? '#facc15');
            $row['href'] = cn_menu_normalizar_href($row['url'] ?? '', $idConcursoTrabajo, $requiereConcurso);
            $row['children'] = [];
            $permitidos[] = $row;
        }

        mysqli_free_result($res);

        $porPadre = [];

        foreach ($permitidos as $item) {
            $parentId = $item['parent_id'] === null ? 0 : (int)$item['parent_id'];

            if (!isset($porPadre[$parentId])) {
                $porPadre[$parentId] = [];
            }

            $porPadre[$parentId][] = $item;
        }

        $construir = function (int $parentId) use (&$construir, &$porPadre): array {
            $salida = [];

            foreach ($porPadre[$parentId] ?? [] as $item) {
                $item['children'] = $construir((int)$item['id_menu']);
                $salida[] = $item;
            }

            return $salida;
        };

        return $construir(0);
    }
}

if (!function_exists('cn_menu_item_activo')) {
    function cn_menu_item_activo(array $item): bool
    {
        $actual = str_replace('\\', '/', (string)($_SERVER['PHP_SELF'] ?? ''));
        $url = str_replace('\\', '/', (string)($item['url'] ?? ''));

        if ($url === '') {
            foreach ($item['children'] ?? [] as $child) {
                if (cn_menu_item_activo($child)) {
                    return true;
                }
            }

            return false;
        }

        $urlLimpia = strtok($url, '?') ?: $url;

        return substr($actual, -strlen($urlLimpia)) === $urlLimpia;
    }
}
