import asyncio
import websockets
import json
from pydub import AudioSegment
import os

# Configuración de tu Bocina IP
IP_BOCINA = "192.168.1.142"
PUERTO_WS = 81

async def _enviar_audio_ws(pcm_data):
    url = f"ws://{IP_BOCINA}:{PUERTO_WS}"
    chunk_size = 1024
    
    try:
        async with websockets.connect(url, ping_timeout=None) as websocket:
            # Esperamos el mensaje de bienvenida
            await websocket.recv() 
            
            chunks_enviados = 0
            for i in range(0, len(pcm_data), chunk_size):
                chunk = pcm_data[i:i + chunk_size]
                await websocket.send(chunk)
                chunks_enviados += 1
                
                # ⚡ EL TRUCO MAESTRO: CONTROL DE FLUJO
                if chunks_enviados % 10 == 0:
                    try:
                        # Python se pausa hasta que el ESP32 mande el "ACK"
                        await asyncio.wait_for(websocket.recv(), timeout=1.0)
                    except asyncio.TimeoutError:
                        pass # Si hay lag en la red, forzamos a seguir para no cortar
                else:
                    await asyncio.sleep(0.002) # Micro-pausa entre paquetes individuales
                    
            # Le damos 1 segundo al ESP32 para reproducir los últimos datos en su memoria
            await asyncio.sleep(1.0) 
            await websocket.send(json.dumps({"cmd": "STOP"}))
            return True
            
    except Exception as e:
        print(f" Error conectando a la bocina IP {IP_BOCINA}: {e}")
        return False

def enviar_archivos_bocina(lista_archivos):
    """
    Recibe una lista de rutas de archivos MP3, los une en un solo track,
    los convierte al formato del ESP32 y los transmite.
    """
    if not lista_archivos:
        return
    
    try:
        audio_final = AudioSegment.empty()
        for archivo in lista_archivos:
            if os.path.exists(archivo):
                segmento = AudioSegment.from_file(archivo)
                audio_final += segmento
        
        audio_mono = audio_final.split_to_mono()[0]
        
        # ⚡ 2. SUBIMOS LA CALIDAD (A 22050 Hz)
        audio_final = audio_mono.set_frame_rate(22050).set_sample_width(2)
        
        # 3. Quitamos el clipping (saturación).
        # Como ya no estamos sumando canales, podemos dejarle más volumen. Le bajaremos solo 2 dB.
        audio_final = audio_final - 2 
        
        # 4. Obtenemos los datos puros
        pcm_data = audio_final.raw_data
        
        # ⚡ 4. TRANSMITIMOS A LA BOCINA (¡Te faltaba esta parte!)
        print(f" Transmitiendo audio a {IP_BOCINA}...")
        asyncio.run(_enviar_audio_ws(pcm_data))
        
    except Exception as e:
        print(f"Error procesando el audio para la bocina: {e}")