#!/usr/bin/env python3
"""
TalkLabs SDK - Exemplos de Ultra-Low Latency Streaming com Redis + spaCy

Este arquivo demonstra o uso do novo método stream_redis() que oferece
latência de ~200-500ms até o primeiro chunk de áudio.

Requisitos:
    pip install talklabs

Execução:
    python examples/redis_streaming_example.py
"""

import asyncio
import os
import time
from talklabs import TalkLabsClient, VoiceSettings


# Configuração
API_KEY = os.getenv("TALKLABS_API_KEY", "tlk_live_HmXz0GrJ0k4nYRpk")
BASE_URL = "https://api.talklabs.com.br"  # ou "http://localhost:5000" para local


# ============================================================
# Exemplo 1: Streaming Básico com Ultra-Low Latency
# ============================================================

async def example_basic_streaming():
    """
    Demonstra streaming básico com latência ultra-baixa.
    Chunks de áudio são recebidos conforme são gerados.
    """
    print("\n" + "="*60)
    print("📡 Exemplo 1: Streaming Básico com Ultra-Low Latency")
    print("="*60)

    client = TalkLabsClient(api_key=API_KEY, base_url=BASE_URL)

    text = """
    Olá! Este é um teste do sistema de streaming com ultra baixa latência.
    O texto está sendo processado com spaCy e enfileirado no Redis.
    Você deve receber o primeiro chunk de áudio em menos de 500 milissegundos!
    """

    start_time = time.time()
    chunk_count = 0
    first_chunk_latency = None

    try:
        async for audio_chunk in client.stream_redis(
            text=text,
            voice="yasmin_alves",
            language="pt",
            speed=1.0
        ):
            chunk_count += 1

            if chunk_count == 1:
                first_chunk_latency = (time.time() - start_time) * 1000
                print(f"\n⚡ Primeiro chunk recebido em {first_chunk_latency:.0f}ms!")

            print(f"🎵 Chunk {chunk_count}: {len(audio_chunk):,} bytes")

            # Aqui você pode reproduzir o chunk imediatamente
            # Ex: play_audio(audio_chunk)

        total_time = (time.time() - start_time) * 1000
        print(f"\n✅ Stream finalizado!")
        print(f"   Total de chunks: {chunk_count}")
        print(f"   Latência do primeiro chunk: {first_chunk_latency:.0f}ms")
        print(f"   Tempo total: {total_time:.0f}ms")

    except Exception as e:
        print(f"❌ Erro: {e}")


# ============================================================
# Exemplo 2: Streaming Incremental (Palavra por Palavra)
# ============================================================

async def example_incremental_streaming():
    """
    Demonstra streaming incremental, simulando digitação em tempo real.
    Texto é enviado palavra por palavra, maximizando responsividade.
    """
    print("\n" + "="*60)
    print("🔄 Exemplo 2: Streaming Incremental (Palavra por Palavra)")
    print("="*60)

    client = TalkLabsClient(api_key=API_KEY, base_url=BASE_URL)

    text = "Olá mundo! Este texto está sendo enviado palavra por palavra em tempo real."

    print(f"📝 Texto: {text}")
    print(f"⏱️  Delay entre palavras: 100ms\n")

    start_time = time.time()
    chunk_count = 0

    try:
        async for audio_chunk in client.stream_redis(
            text=text,
            voice="yasmin_alves",
            incremental=True,     # Modo incremental ativado
            word_delay=0.1        # 100ms entre palavras
        ):
            chunk_count += 1
            elapsed = (time.time() - start_time) * 1000
            print(f"🎵 [{elapsed:6.0f}ms] Chunk {chunk_count}: {len(audio_chunk):,} bytes")

        print(f"\n✅ Streaming incremental finalizado!")
        print(f"   Total: {chunk_count} chunks em {elapsed:.0f}ms")

    except Exception as e:
        print(f"❌ Erro: {e}")


# ============================================================
# Exemplo 3: Salvar Áudio em Arquivo
# ============================================================

async def example_save_to_file():
    """
    Demonstra como salvar chunks progressivamente em arquivo.
    """
    print("\n" + "="*60)
    print("💾 Exemplo 3: Salvar Áudio Progressivamente")
    print("="*60)

    client = TalkLabsClient(api_key=API_KEY, base_url=BASE_URL)

    text = "Este áudio será salvo em um arquivo conforme os chunks chegam."
    output_file = "output_redis_streaming.wav"

    print(f"📝 Texto: {text}")
    print(f"📁 Arquivo de saída: {output_file}\n")

    chunk_count = 0

    try:
        with open(output_file, "wb") as f:
            async for audio_chunk in client.stream_redis(
                text=text,
                voice="yasmin_alves"
            ):
                chunk_count += 1
                f.write(audio_chunk)
                print(f"💾 Chunk {chunk_count} salvo ({len(audio_chunk):,} bytes)")

        print(f"\n✅ Áudio salvo em {output_file}!")
        print(f"   Total de chunks: {chunk_count}")

    except Exception as e:
        print(f"❌ Erro: {e}")


# ============================================================
# Exemplo 4: Configurações Avançadas de Voz
# ============================================================

async def example_advanced_settings():
    """
    Demonstra uso de configurações avançadas de voz.
    """
    print("\n" + "="*60)
    print("⚙️  Exemplo 4: Configurações Avançadas de Voz")
    print("="*60)

    client = TalkLabsClient(api_key=API_KEY, base_url=BASE_URL)

    settings = VoiceSettings(
        stability=0.85,           # Mais estável
        similarity_boost=0.75,
        style=0.2,                # Pouco expressivo
        use_speaker_boost=True
    )

    text = "Esta voz está usando configurações customizadas para maior clareza."

    print(f"📝 Texto: {text}")
    print(f"⚙️  Configurações:")
    print(f"   - Stability: {settings.stability}")
    print(f"   - Similarity Boost: {settings.similarity_boost}")
    print(f"   - Style: {settings.style}")
    print(f"   - Speaker Boost: {settings.use_speaker_boost}\n")

    chunk_count = 0

    try:
        async for audio_chunk in client.stream_redis(
            text=text,
            voice="yasmin_alves",
            voice_settings=settings,
            speed=1.2  # 20% mais rápido
        ):
            chunk_count += 1
            print(f"🎵 Chunk {chunk_count}: {len(audio_chunk):,} bytes")

        print(f"\n✅ Stream finalizado com {chunk_count} chunks!")

    except Exception as e:
        print(f"❌ Erro: {e}")


# ============================================================
# Exemplo 5: Comparação de Latência (Redis vs HTTP)
# ============================================================

async def example_latency_comparison():
    """
    Compara latência entre streaming Redis e HTTP tradicional.
    """
    print("\n" + "="*60)
    print("⚡ Exemplo 5: Comparação de Latência")
    print("="*60)

    client = TalkLabsClient(api_key=API_KEY, base_url=BASE_URL)

    text = "Este é um texto curto para comparação de latência."

    # Teste 1: Redis Streaming
    print("\n🚀 Teste 1: Redis Streaming (Ultra-Low Latency)")
    start = time.time()
    chunk_count_redis = 0

    try:
        async for audio_chunk in client.stream_redis(
            text=text,
            voice="yasmin_alves"
        ):
            if chunk_count_redis == 0:
                first_chunk_redis = (time.time() - start) * 1000
                print(f"   ⚡ Primeiro chunk: {first_chunk_redis:.0f}ms")
            chunk_count_redis += 1

        total_redis = (time.time() - start) * 1000
        print(f"   ✅ Total: {total_redis:.0f}ms ({chunk_count_redis} chunks)")

    except Exception as e:
        print(f"   ❌ Erro: {e}")

    # Teste 2: HTTP Streaming
    print("\n🌊 Teste 2: HTTP Streaming (Tradicional)")
    start = time.time()
    chunk_count_http = 0

    try:
        for audio_chunk in client.generate_stream(
            text=text,
            voice="yasmin_alves"
        ):
            if chunk_count_http == 0:
                first_chunk_http = (time.time() - start) * 1000
                print(f"   ⏱️  Primeiro chunk: {first_chunk_http:.0f}ms")
            chunk_count_http += 1

        total_http = (time.time() - start) * 1000
        print(f"   ✅ Total: {total_http:.0f}ms ({chunk_count_http} chunks)")

    except Exception as e:
        print(f"   ❌ Erro: {e}")

    # Resumo
    print("\n📊 Resumo da Comparação:")
    print(f"   Redis: {first_chunk_redis:.0f}ms (primeiro chunk)")
    print(f"   HTTP:  {first_chunk_http:.0f}ms (primeiro chunk)")
    improvement = ((first_chunk_http - first_chunk_redis) / first_chunk_http) * 100
    print(f"   Melhoria: {improvement:.1f}% mais rápido! 🎯")


# ============================================================
# Menu Principal
# ============================================================

async def main():
    """
    Executa todos os exemplos.
    """
    print("\n" + "="*60)
    print("🎙️  TalkLabs SDK - Exemplos de Redis Streaming")
    print("="*60)
    print(f"\n🔑 API Key: {API_KEY[:20]}...")
    print(f"🌐 Base URL: {BASE_URL}")

    # Escolha quais exemplos executar
    examples = [
        ("Streaming Básico", example_basic_streaming),
        ("Streaming Incremental", example_incremental_streaming),
        ("Salvar em Arquivo", example_save_to_file),
        ("Configurações Avançadas", example_advanced_settings),
        ("Comparação de Latência", example_latency_comparison),
    ]

    print("\n📋 Exemplos Disponíveis:")
    for i, (name, _) in enumerate(examples, 1):
        print(f"   {i}. {name}")

    print("\n▶️  Executando todos os exemplos...\n")

    for name, example_func in examples:
        try:
            await example_func()
            await asyncio.sleep(1)  # Pausa entre exemplos
        except KeyboardInterrupt:
            print("\n\n⚠️  Interrompido pelo usuário")
            break
        except Exception as e:
            print(f"\n❌ Erro no exemplo '{name}': {e}")
            continue

    print("\n" + "="*60)
    print("✅ Todos os exemplos foram executados!")
    print("="*60)


if __name__ == "__main__":
    # Executa os exemplos
    asyncio.run(main())
