/*
    He hecho este sistema para cifrar los audios y no puedan ser accesibles (mantiendo cache) y de que me sirve si el blob es accesible y puede reproducir el audio en la pagina y descargarlo?!!!!
    */
   

    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`);
                }
            }


            const audioBuffer = concatenateUint8Arrays(decryptedChunks);
            const audioBlob = new Blob([audioBuffer], { type: 'audio/mpeg' });
            const blobUrl = URL.createObjectURL(audioBlob);
            
            await validateAudio(blobUrl);
            
            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);
        });