function loadAudio(postId, audioUrl, container, playOnLoad) {
    if (!postId || container.dataset.audioLoaded) return;

    console.log('Cargando audio:', {postId, audioUrl});

    const loadWithServiceWorker = async () => {
        try {
            if (navigator.serviceWorker.controller) {
                console.log('Usando Service Worker para cargar audio');
                await window.we(postId, audioUrl, container, playOnLoad);
            } else {
                console.log('Service Worker no disponible, usando carga normal');
                await window.we(postId, audioUrl, container, playOnLoad);
            }
            container.dataset.audioLoaded = 'true';
        } catch (error) {
            console.error('Error cargando audio:', error);
        }
    };

    loadWithServiceWorker();
}

window.we = function (postId, audioUrl, container, playOnLoad = false) {
    // Verificaciones iniciales
    verifyAudioSettings();

    if (!audioSettings || !audioSettings.nonce) {
        console.error('audioSettings no está configurado correctamente');
        showError(container, 'Error de configuración');
        return;
    }

    if (!window.wavesurfers) {
        window.wavesurfers = {};
    }

    const MAX_RETRIES = 0;
    console.log(`Iniciando carga de audio - PostID: ${postId}`);


    function concatenateUint8Arrays(arrays) {
        let totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
        let result = new Uint8Array(totalLength);
        let offset = 0;
    
        for (let array of arrays) {
            result.set(array, offset);
            offset += array.length;
        }
    
        return result;
    }
   

    async function loadAndPlayAudioStream(retryCount = 0) {
        try {
            window.audioLoading = true;
            const finalAudioUrl = buildAudioUrl(audioUrl, audioSettings.nonce);
    
            const response = await fetch(finalAudioUrl, {
                method: 'GET',
                credentials: 'same-origin',
                headers: {
                    'X-WP-Nonce': audioSettings.nonce,
                    'X-Requested-With': 'XMLHttpRequest',
                    Accept: 'audio/mpeg',
                    Range: 'bytes=0-'
                }
            });
    
            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }
    
            const reader = response.body.getReader();
            const iv = response.headers.get('X-Encryption-IV');
    
            if (!iv) {
                throw new Error('No se recibió el IV en los encabezados de la respuesta');
            }
    
            const ivArray = Uint8Array.from(atob(iv), c => c.charCodeAt(0));
            let currentIV = ivArray;
    
            const contentLengthHeader = response.headers.get('Content-Length');
            const contentLength = contentLengthHeader ? parseInt(contentLengthHeader) : -1;
    
            console.log(`Content-Length obtenido: ${contentLength}`);
    
            let buffer = new Uint8Array(0);
            let receivedLength = 0;
    
            // **Agrega esta línea para declarar decryptedChunks**
            let decryptedChunks = [];
    
            while (true) {
                const { done, value } = await reader.read();
                console.log('Chunk leído:', { done, value });
    
                if (done) {
                    console.log('Transmisión completa');
                    break;
                }
    
                if (value && value.length > 0) {
                    // Añadir los nuevos datos al buffer
                    let tmp = new Uint8Array(buffer.length + value.length);
                    tmp.set(buffer, 0);
                    tmp.set(value, buffer.length);
                    buffer = tmp;
    
                    receivedLength += value.length;
    
                    // Procesar el buffer
                    let offset = 0;
    
                    while (buffer.length - offset >= 4) {
                        // Leer el prefijo de longitud
                        const lengthView = new DataView(buffer.buffer, buffer.byteOffset + offset, 4);
                        const chunkLength = lengthView.getUint32(0, false); // Big-endian
    
                        // Verificar si tenemos suficientes datos para procesar el chunk
                        if (buffer.length - offset >= 4 + chunkLength) {
                            // Extraer los datos encriptados
                            const encryptedData = buffer.subarray(offset + 4, offset + 4 + chunkLength);
    
                            console.log('Procesando chunk:', {
                                totalLength: buffer.byteLength,
                                chunkLength: chunkLength,
                                dataLength: encryptedData.byteLength
                            });
    
                            try {
                                // Desencriptar el chunk
                                const decryptedData = await decryptAudioData(encryptedData, currentIV, audioSettings.key);
                                decryptedChunks.push(new Uint8Array(decryptedData));
    
                                // Actualizar el IV (últimos 16 bytes de encryptedData)
                                if (encryptedData.byteLength >= 16) {
                                    currentIV = encryptedData.subarray(encryptedData.byteLength - 16);
                                } else {
                                    throw new Error('encryptedData es demasiado pequeño para obtener el IV');
                                }
    
                            } catch (error) {
                                console.error('Error desencriptando chunk:', error);
                                throw error;
                            }
    
                            // Mover el offset más allá de este chunk
                            offset += 4 + chunkLength;
                        } else {
                            // No tenemos suficientes datos aún
                            break;
                        }
                    }
    
                    // Eliminar los datos procesados del buffer
                    if (offset > 0) {
                        buffer = buffer.subarray(offset);
                    }
    
                    console.log(`Procesado ${receivedLength} bytes`);
                }
            }

            /*

           Tengo este problema aqui
            Procesando chunk: 
            Object { totalLength: 20936, chunkLength: 8208, dataLength: 8208 }
            wavejs.js:347:37
            Procesado 160540 bytes wavejs.js:383:29
            Chunk leído: 
            Object { done: true, value: undefined }
            wavejs.js:318:25
            Transmisión completa wavejs.js:321:29
            GET
            https://2upra.com/sample/jazzy-hammond-organ-sample/[object Blob]
            NS_BINDING_ABORTED

            Error en loadAndPlayAudioStream: 
            error { target: audio, isTrusted: true, srcElement: audio, currentTarget: audio, eventPhase: 2, bubbles: false, cancelable: false, returnValue: true, defaultPrevented: false, composed: false, … }
            wavejs.js:404:21
            Load error: 
            error { target: audio, isTrusted: true, srcElement: audio, currentTarget: audio, eventPhase: 2, bubbles: false, cancelable: false, returnValue: true, defaultPrevented: false, composed: false, … }
            */

            const audioBuffer = concatenateUint8Arrays(decryptedChunks);
            const audioBlob = new Blob([audioBuffer], { type: 'audio/mpeg' });

            await validateAudio(audioBlob);
    
            const wavesurfer = initWavesurfer(container);
            window.wavesurfers[postId] = wavesurfer;

            await new Promise(resolve => {
                wavesurfer.once('ready', resolve);
                wavesurfer.load(blobUrl);
            });
    
            handleWaveSurferEvents(wavesurfer, container, postId, blobUrl);
    
        } catch (error) {
            console.error('Error en loadAndPlayAudioStream:', error);
            handleLoadError(error, retryCount, container);
        }
    }

async function decryptAudioData(encryptedData, ivArray, key) {
        try {
            // Convertir la clave hexadecimal a Uint8Array si aún no la has cacheado
            if (!window.cachedKeyArray) {
                window.cachedKeyArray = new Uint8Array(key.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
            }
            const keyArray = window.cachedKeyArray;
    
            // Importar la clave
            const cryptoKey = await crypto.subtle.importKey(
                'raw',
                keyArray.buffer,
                { name: 'AES-CBC', length: 256 },
                false,
                ['decrypt']
            );
    
            // Desencriptar los datos
            const decryptedData = await crypto.subtle.decrypt(
                { name: 'AES-CBC', iv: ivArray },
                cryptoKey,
                encryptedData
            );
    
            return decryptedData;
        } catch (error) {
            console.error('Error en desencriptación de chunk:', error);
            throw error;
        }
    }

    // Función para construir la URL de audio
    function buildAudioUrl(audioUrl, nonce) {
        const urlObj = new URL(audioUrl);
        if (!urlObj.searchParams.has('_wpnonce')) {
            urlObj.searchParams.append('_wpnonce', nonce);
        }
        return urlObj.toString();
    }

    function createAudioBlobUrl(audioData) {
        const audioBlob = new Blob([audioData], {type: 'audio/mpeg'});
        return URL.createObjectURL(audioBlob);
    }

    async function validateAudio(blobUrl) {
        const audio = new Audio();
        audio.src = blobUrl;

        await new Promise((resolve, reject) => {
            audio.addEventListener('canplaythrough', resolve);
            audio.addEventListener('error', reject);
            audio.load();
        });
    }

    // Función para manejar los eventos de Wavesurfer
    function handleWaveSurferEvents(wavesurfer, container, postId, blobUrl) {
        const waveformBackground = container.querySelector('.waveform-background');
        if (waveformBackground) {
            waveformBackground.style.display = 'none';
        }

        wavesurfer.on('ready', () => {
            window.audioLoading = false;
            container.dataset.audioLoaded = 'true';
            const loadingElement = container.querySelector('.waveform-loading');
            if (loadingElement) {
                loadingElement.style.display = 'none';
            }

            // Generar y enviar la imagen de la forma de onda
            handleWaveformGeneration(wavesurfer, container, postId);

            // Reproducir si es necesario
            if (playOnLoad) {
                wavesurfer.play();
            }
        });

        wavesurfer.on('destroy', () => {
            URL.revokeObjectURL(blobUrl);
        });

        wavesurfer.on('error', error => {
            console.error('WaveSurfer error:', error);
            if (retryCount < MAX_RETRIES) {
                setTimeout(() => loadAndPlayAudioStream(retryCount + 1), 3000);
            }
        });
    }

    // Función para manejar errores de carga
    function handleLoadError(error, retryCount, container) {
        console.error('Load error:', error);
        if (retryCount < MAX_RETRIES) {
            setTimeout(() => loadAndPlayAudioStream(retryCount + 1), 3000);
        } else {
            showError(container, 'Error al cargar el audio.');
        }
    }

    // Función para manejar la generación de la forma de onda
    function handleWaveformGeneration(wavesurfer, container, postId) {
        const waveCargada = container.getAttribute('data-wave-cargada') === 'true';
        const isMobile = /Mobi|Android|iPhone|iPad|iPod/.test(navigator.userAgent);

        if (!waveCargada && !isMobile && !container.closest('.LISTWAVESAMPLE')) {
            setTimeout(() => {
                const image = generateWaveformImage(wavesurfer);
                sendImageToServer(image, postId);
            }, 1);
        }
    }

    // Iniciar la carga
    loadAndPlayAudioStream();
};

// La función que inicializa WaveSurfer con los estilos y configuraciones deseados
function initWavesurfer(container) {