/*
En la venta de red se ve la transferencia https://2upra.com/wp-json/1/v1/2?token=MjgxMDk4fDE5MjQ5MDU2MDB8Y2FjaGVkfGYwNzY1MjU1NjIzZDk0YzI2MmYwMTU2NDY4MDY3OGFlfDk5OTk5OXwyNmFkN2Y5ZmRiNGNmMGE0NzkxNTc0Nzk2MjIxMDVjYjRjOTU2Y2Y3MzRhOGQ2Mzc3M2ZhOTdhMmFlYjU5YmRh&_wpnonce=982f26a68e y es completamente accesible y reproducible, yo no quiero eso y no se hacer para evitarlo sin dañar el hecho que quiero lo usuarios puedan cachear los audios en el navegador

por cierto estoy usando esto

// sw.js
const CACHE_NAME = 'audio-cache-v1';

self.addEventListener('install', event => {
    self.skipWaiting();
});

self.addEventListener('activate', event => {
    event.waitUntil(clients.claim());
});

// sw.js
self.addEventListener('fetch', event => {
    if (event.request.url.includes('/wp-json/1/v1/2')) {
        event.respondWith(
            caches.open(CACHE_NAME).then(async cache => {
                try {
                    const response = await fetch(event.request.clone(), {
                        credentials: 'same-origin',
                        headers: {
                            'X-Requested-With': 'XMLHttpRequest',
                            //'Accept': 'audio/mpeg',
                            //'Range': 'bytes=0-',
                            'X-WP-Nonce': event.request.headers.get('X-WP-Nonce')
                        }
                    });

                    if (!response.ok && response.status !== 206) {
                        throw new Error(`HTTP error! status: ${response.status}`);
                    }

                    // No cachear respuestas parciales
                    if (response.status === 206) {
                        return response;
                    }

                    const clonedResponse = response.clone();
                    cache.put(event.request, clonedResponse);
                    return response;
                } catch (error) {
                    console.error('Fetch error:', error);
                    const cachedResponse = await cache.match(event.request);
                    if (cachedResponse) {
                        return cachedResponse;
                    }
                    throw error;
                }
            })
        );
    }
});
*/

window.we = function (postId, audioUrl, container, playOnLoad = false) {
    if (!window.wavesurfers) {
        window.wavesurfers = {};
    }

    const MAX_RETRIES = 3;
    //console.log(`Intentando cargar audio para postId=${postId}, URL=${audioUrl}`);

    const loadAndPlayAudioStream = (retryCount = 0) => {
        if (retryCount >= MAX_RETRIES) {
            //console.error(`No se pudo cargar el audio para postId=${postId} después de varios intentos`);
            container.querySelector('.waveform-loading').style.display = 'none';
            container.querySelector('.waveform-message').style.display = 'block';
            container.querySelector('.waveform-message').textContent = 'Error al cargar el audio.';
            return;
        }

        window.audioLoading = true;

        fetch(audioUrl, {
            method: 'GET',
            credentials: 'same-origin',
            headers: {
                'X-WP-Nonce': audioSettings.nonce,
                'X-Requested-With': 'XMLHttpRequest',
                //Accept: 'audio/mpeg,audio/*;q=0.9,*/*;q=0.8'
            }
        })
        .then(response => {
            if (!response.ok) throw new Error('Respuesta de red no satisfactoria');
            return response;
        })
        .then(response => {
            const reader = response.body.getReader();
            return new ReadableStream({
                start(controller) {
                    return pump();
                    function pump() {
                        return reader.read().then(({ done, value }) => {
                            if (done) {
                                controller.close();
                                return;
                            }
                            controller.enqueue(value);
                            return pump();
                        });
                    }
                }
            });
        })
        .then(stream => new Response(stream))
        .then(response => response.blob())
        .then(blob => {
            const audioBlobUrl = URL.createObjectURL(blob);

            // Inicializar wavesurfer y guardarlo en el objeto global
            const wavesurfer = initWavesurfer(container);
            window.wavesurfers[postId] = wavesurfer;

            wavesurfer.load(audioBlobUrl);

            const waveformBackground = container.querySelector('.waveform-background');
            if (waveformBackground) {
                waveformBackground.style.display = 'none';
            }

            y del lado del servidor

            function audioUrlSegura($audio_id)
            {
                guardarLog("Generando URL segura para audio ID: " . $audio_id);
            
                $user_id = get_current_user_id();
                if (usuarioEsAdminOPro($user_id)) {
                    $url = site_url("/wp-json/1/v1/audio-pro/{$audio_id}");
                    guardarLog("URL generada para admin/pro: " . $url);
                    return $url;
                }
            
                $token = tokenAudio($audio_id);
                if (!$token) {
                    guardarLog("Error generando token para audio ID: " . $audio_id);
                    return new WP_Error('invalid_audio_id', 'Audio ID inválido.');
                }
            
                $nonce = wp_create_nonce('wp_rest');
                $url = site_url("/wp-json/1/v1/2?token=" . urlencode($token) . '&_wpnonce=' . $nonce);
                guardarLog("URL generada para usuario normal: " . $url);
                return $url;
            }
            
            function bloquear_acceso_directo_archivos()
            {
                if (strpos($_SERVER['REQUEST_URI'], '/wp-content/uploads/') !== false) {
                    $referer = $_SERVER['HTTP_REFERER'] ?? '';
                    if (strpos($referer, home_url()) === false) {
                        wp_die('Acceso denegado: no puedes descargar este archivo directamente.', 'Acceso denegado', array('response' => 403));
                    }
                }
            }
            add_action('init', 'bloquear_acceso_directo_archivos');
            
            function decrementaUsosToken($unique_id)
            {
                // Solo decrementar si el cacheo del navegador está desactivado
                if (defined('ENABLE_BROWSER_AUDIO_CACHE') && ENABLE_BROWSER_AUDIO_CACHE) {
                    return; // No decrementar para tokens cacheados
                }
            
                guardarLog("Decrementando usos del token: $unique_id");
                $key = 'audio_token_' . $unique_id;
                $usos_restantes = get_transient($key);
            
                if ($usos_restantes !== false && $usos_restantes > 0) {
                    $usos_restantes--;
                    if ($usos_restantes > 0) {
                        set_transient($key, $usos_restantes, get_option('transient_timeout_' . $key));
                    } else {
                        delete_transient($key);
                    }
                }
            }
            
            add_action('rest_api_init', function () {
                guardarLog('Registrando rutas REST API');
            
                // Ruta para usuarios pro
                register_rest_route('1/v1', '/audio-pro/(?P<id>\d+)', array(
                    'methods' => 'GET',
                    'callback' => 'audioStreamEndPro',
                    'permission_callback' => function () {
                        return usuarioEsAdminOPro(get_current_user_id());
                    },
                    'args' => array(
                        'id' => array(
                            'validate_callback' => function ($param) {
                                return is_numeric($param);
                            }
                        ),
                    ),
                ));
            
                // Ruta para usuarios normales
                register_rest_route('1/v1', '/2', array(
                    'methods' => 'GET',
                    'callback' => 'audioStreamEnd',
                    'args' => array(
                        'token' => array(
                            'required' => true,
                        ),
                    ),
                    'permission_callback' => function ($request) {
                        guardarLog('Verificando permiso para token: ' . $request->get_param('token'));
                        return verificarAudio($request->get_param('token'));
                    }
                ));
            
                guardarLog('Rutas REST API registradas');
            });
            
            function tokenAudio($audio_id)
            {
                guardarLog("Generando token para audio_id: $audio_id");
            
                if (!preg_match('/^[a-zA-Z0-9_-]+$/', $audio_id)) {
                    guardarLog("Error: audio_id inválido: $audio_id");
                    return false;
                }
            
                // Si el cacheo del navegador está activado, generamos un token más persistente
                if (defined('ENABLE_BROWSER_AUDIO_CACHE') && ENABLE_BROWSER_AUDIO_CACHE) {
                    // Usar una fecha fija para que el token sea consistente
                    $expiration = strtotime('2030-12-31'); // Fecha lejana fija
                    $user_ip = 'cached'; // No usamos IP para permitir el cacheo
                    $unique_id = md5($audio_id . $_ENV['AUDIOCLAVE']); // ID único pero consistente
                    $max_usos = 999999; // Número alto de usos
            
                    $data = $audio_id . '|' . $expiration . '|' . $user_ip . '|' . $unique_id;
                    $signature = hash_hmac('sha256', $data, $_ENV['AUDIOCLAVE']);
                    $token = base64_encode($data . '|' . $max_usos . '|' . $signature);
            
                    // No necesitamos almacenar el contador de usos para tokens cacheados
                    return $token;
                } else {
                    // Comportamiento original para cuando el cacheo está desactivado
                    $expiration = time() + 3600;
                    $user_ip = $_SERVER['REMOTE_ADDR'];
                    $unique_id = uniqid('', true);
                    $max_usos = 3;
            
                    $data = $audio_id . '|' . $expiration . '|' . $user_ip . '|' . $unique_id;
                    $signature = hash_hmac('sha256', $data, $_ENV['AUDIOCLAVE']);
                    $token = base64_encode($data . '|' . $max_usos . '|' . $signature);
            
                    set_transient('audio_token_' . $unique_id, $max_usos, 3600);
            
                    guardarLog("Token generado exitosamente: $token");
                    return $token;
                }
            }
            
            
            function verificarAudio($token)
            {
                guardarLog("Verificando token: $token");
                guardarLog("Iniciando verificación de audio");
                guardarLog("Token recibido: " . $token);
                guardarLog("Headers recibidos: " . print_r(getallheaders(), true));
            
                if (empty($token)) {
                    guardarLog("Error: token vacío");
                    return false;
                }
            
                // Verificar referer y headers
                if (!isset($_SERVER['HTTP_REFERER']) || !isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
                    guardarLog("Error: Faltan headers requeridos");
                    return false;
                }
            
                $referer_host = parse_url($_SERVER['HTTP_REFERER'], PHP_URL_HOST);
                if ($referer_host !== '2upra.com') {
                    guardarLog("Error: referer no válido");
                    return false;
                }
            
                if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') {
                    guardarLog("Error: No es una petición AJAX");
                    return false;
                }
            
                $decoded = base64_decode($token);
                $parts = explode('|', $decoded);
                if (count($parts) !== 6) {
                    guardarLog("Error: número incorrecto de partes en el token");
                    return false;
                }
                guardarLog("Partes del token: " . print_r($parts, true));
            
                list($audio_id, $expiration, $user_ip, $unique_id, $max_usos, $signature) = $parts;
            
                if (defined('ENABLE_BROWSER_AUDIO_CACHE') && ENABLE_BROWSER_AUDIO_CACHE) {
                    // Generar una clave única para esta sesión y audio
                    $session_key = 'audio_session_' . $audio_id . '_' . $_SERVER['REMOTE_ADDR'];
                    $cache_key = 'audio_access_' . $audio_id . '_' . $_SERVER['REMOTE_ADDR'];
            
                    // Verificar la firma
                    $data = $audio_id . '|' . $expiration . '|' . $user_ip . '|' . $unique_id;
                    $expected_signature = hash_hmac('sha256', $data, $_ENV['AUDIOCLAVE']);
            
                    if (!hash_equals($expected_signature, $signature)) {
                        guardarLog("Error: firma no válida");
                        return false;
                    }
            
                    // Verificar sesión actual
                    $current_session = get_transient($session_key);
            
                    if ($current_session === false) {
                        // Primera solicitud en esta sesión
                        set_transient($session_key, $token, 3600); // 1 hora
                        set_transient($cache_key, 1, 3600); // Contador de accesos
                        return true;
                    } else {
                        // Verificar si es una solicitud válida desde la página
                        $access_count = get_transient($cache_key);
            
                        if (
                            $access_count !== false &&
                            $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest' &&
                            strpos($_SERVER['HTTP_REFERER'], '2upra.com') !== false
                        ) {
            
                            set_transient($cache_key, $access_count + 1, 3600);
                            return true;
                        }
            
                        guardarLog("Error: acceso directo o no autorizado");
                        return false;
                    }
                } else {
                    // Comportamiento original para modo sin caché
                    if ($_SERVER['REMOTE_ADDR'] !== $user_ip) {
                        guardarLog("Error: IP no coincide");
                        return false;
                    }
            
                    if (time() > $expiration) {
                        guardarLog("Error: token expirado");
                        return false;
                    }
            
                    $usos_restantes = get_transient('audio_token_' . $unique_id);
                    if ($usos_restantes === false || $usos_restantes <= 0) {
                        return false;
                    }
            
                    $data = $audio_id . '|' . $expiration . '|' . $user_ip . '|' . $unique_id;
                    $expected_signature = hash_hmac('sha256', $data, $_ENV['AUDIOCLAVE']);
            
                    if (hash_equals($expected_signature, $signature)) {
                        decrementaUsosToken($unique_id);
                        return true;
                    }
            
                    return false;
                }
            }
            
            
            
            function audioStreamEnd($data)
            {