<?php

declare(strict_types=1);

function h(?string $s): string
{
    return htmlspecialchars((string) $s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

function redirect(string $path): void
{
    if (str_starts_with($path, 'http')) {
        header('Location: ' . $path);
    } else {
        $path = str_starts_with($path, '/') ? $path : '/' . ltrim($path, '/');
        header('Location: ' . BASE_URL . $path);
    }
    exit;
}

function url(string $path = ''): string
{
    $path = ltrim($path, '/');
    return rtrim(BASE_URL, '/') . ($path !== '' ? '/' . $path : '');
}

function flash(string $key, ?string $message = null): mixed
{
    if ($message === null) {
        $msg = $_SESSION['_flash'][$key] ?? null;
        unset($_SESSION['_flash'][$key]);
        return $msg;
    }
    $_SESSION['_flash'][$key] = $message;
    return null;
}

function csrf_token(): string
{
    if (empty($_SESSION['_csrf'])) {
        $_SESSION['_csrf'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['_csrf'];
}

function csrf_field(): string
{
    return '<input type="hidden" name="_csrf" value="' . h(csrf_token()) . '">';
}

function verify_csrf(): void
{
    $t = $_POST['_csrf'] ?? '';
    if ($t === '' || !hash_equals($_SESSION['_csrf'] ?? '', $t)) {
        http_response_code(403);
        exit('Solicitud no válida.');
    }
}

function is_readonly_user(): bool
{
    $p = $_SESSION['user']['perfiles'] ?? [];
    return in_array('consulta', $p, true) && count($p) === 1;
}

function can_manage_data(): bool
{
    return !is_readonly_user();
}

function has_any_role(array $codes): bool
{
    $have = $_SESSION['user']['perfiles'] ?? [];
    foreach ($codes as $c) {
        if (in_array($c, $have, true)) {
            return true;
        }
    }
    return false;
}

function can_manage_users(): bool
{
    return has_any_role(['superadmin', 'admin']);
}

/** Ruta absoluta al directorio de escudos (uploads/escudos). */
function uploads_escudos_path(): string
{
    return APP_ROOT . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'escudos';
}

/**
 * Guarda un archivo subido como escudo. Devuelve ruta relativa p. ej. uploads/escudos/xxx.png o null si falla.
 */
function guardar_escudo_subida(array $file): ?string
{
    if (($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
        return null;
    }
    $allowed = [
        'image/jpeg' => 'jpg',
        'image/png' => 'png',
        'image/webp' => 'webp',
        'image/gif' => 'gif',
    ];
    $tmp = $file['tmp_name'] ?? '';
    if ($tmp === '' || !is_uploaded_file($tmp)) {
        return null;
    }
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mime = $finfo->file($tmp);
    if (!isset($allowed[$mime])) {
        return null;
    }
    $ext = $allowed[$mime];
    $name = 'escudo_' . bin2hex(random_bytes(8)) . '.' . $ext;
    $dir = uploads_escudos_path();
    if (!is_dir($dir) && !mkdir($dir, 0755, true) && !is_dir($dir)) {
        return null;
    }
    $dest = $dir . DIRECTORY_SEPARATOR . $name;
    if (!move_uploaded_file($tmp, $dest)) {
        return null;
    }
    return 'uploads/escudos/' . $name;
}

/** Elimina el fichero físico si existe (ruta relativa al proyecto, solo uploads/escudos/). */
function eliminar_archivo_escudo(?string $rutaRelativa): void
{
    if ($rutaRelativa === null || $rutaRelativa === '') {
        return;
    }
    $norm = str_replace('\\', '/', $rutaRelativa);
    if (!str_starts_with($norm, 'uploads/escudos/')) {
        return;
    }
    $full = APP_ROOT . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $norm);
    if (is_file($full)) {
        @unlink($full);
    }
}
