#!/usr/bin/env python3
"""
LiveTalker Simple Voice Server
Working voice input without complex dependencies
"""

import asyncio
import json
import logging
import time
import base64
import numpy as np
from typing import Dict, Any
import math

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.responses import HTMLResponse
from fastapi.middleware.cors import CORSMiddleware
import uvicorn

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = FastAPI(title="LiveTalker Simple Voice Server")

# Enable CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

active_connections: Dict[str, Dict] = {}

def simple_vad(audio_data: np.ndarray, threshold: float = 0.01) -> tuple:
    """Simple energy-based voice activity detection"""
    if len(audio_data) == 0:
        return False, 0.0
    
    # Calculate RMS energy
    rms = np.sqrt(np.mean(audio_data ** 2))
    
    # Simple threshold-based detection
    is_speech = rms > threshold
    confidence = min(rms / threshold, 1.0) if threshold > 0 else 0.0
    
    return is_speech, confidence

@app.get("/")
async def root():
    """Main interface with working voice input"""
    html_content = """
<!DOCTYPE html>
<html>
<head>
    <title>LiveTalker - Real Voice Input</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        * { box-sizing: border-box; }
        body { 
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; 
            margin: 0; padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            min-height: 100vh;
        }
        .container { 
            max-width: 1000px; 
            margin: 0 auto; 
            background: rgba(255,255,255,0.1);
            padding: 30px;
            border-radius: 20px;
            backdrop-filter: blur(15px);
            box-shadow: 0 8px 32px rgba(0,0,0,0.2);
        }
        h1 { 
            text-align: center; 
            margin-bottom: 30px;
            font-size: 2.5em;
            text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
        }
        .status-card { 
            padding: 20px; 
            margin: 20px 0; 
            border-radius: 12px; 
            background: rgba(255,255,255,0.15);
            border: 2px solid transparent;
            transition: all 0.3s ease;
        }
        .status-card.active { border-color: #4CAF50; background: rgba(76,175,80,0.25); }
        .status-card.listening { border-color: #FF9800; background: rgba(255,152,0,0.25); }
        .status-card.speaking { border-color: #2196F3; background: rgba(33,150,243,0.25); }
        
        .controls { 
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin: 30px 0;
        }
        
        .btn { 
            padding: 15px 25px; 
            border: none; 
            border-radius: 10px; 
            background: #4CAF50; 
            color: white; 
            cursor: pointer; 
            font-size: 16px;
            font-weight: 600;
            transition: all 0.3s ease;
            text-decoration: none;
            display: inline-block;
            text-align: center;
        }
        .btn:hover { background: #45a049; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.2); }
        .btn:disabled { background: #666; cursor: not-allowed; transform: none; opacity: 0.6; }
        .btn.danger { background: #f44336; }
        .btn.danger:hover { background: #da190b; }
        .btn.primary { background: #2196F3; }
        .btn.primary:hover { background: #1976D2; }
        
        .mic-section {
            text-align: center;
            margin: 40px 0;
        }
        
        .mic-button { 
            background: #f44336; 
            font-size: 24px; 
            padding: 30px;
            border-radius: 50%;
            width: 100px;
            height: 100px;
            margin: 20px auto;
            display: flex;
            align-items: center;
            justify-content: center;
            border: none;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        .mic-button:hover { transform: scale(1.05); }
        .mic-button.recording { 
            background: #ff1744; 
            animation: pulse 1s infinite;
            box-shadow: 0 0 30px rgba(255,23,68,0.5);
        }
        
        @keyframes pulse {
            0%, 100% { opacity: 1; transform: scale(1); }
            50% { opacity: 0.8; transform: scale(1.1); }
        }
        
        .vad-display {
            margin: 30px 0;
            padding: 20px;
            background: rgba(0,0,0,0.3);
            border-radius: 12px;
        }
        
        .vad-bar {
            width: 100%;
            height: 40px;
            background: rgba(255,255,255,0.2);
            border-radius: 20px;
            overflow: hidden;
            position: relative;
            margin: 15px 0;
        }
        
        .vad-level {
            height: 100%;
            background: linear-gradient(90deg, #4CAF50, #8BC34A, #FFC107, #FF5722);
            width: 0%;
            transition: width 0.1s ease;
            border-radius: 20px;
        }
        
        .vad-text {
            text-align: center;
            font-size: 18px;
            font-weight: bold;
            margin-top: 10px;
        }
        
        .conversation {
            background: rgba(0,0,0,0.4);
            border-radius: 15px;
            padding: 20px;
            margin: 20px 0;
            max-height: 400px;
            overflow-y: auto;
            min-height: 200px;
        }
        
        .message {
            margin: 15px 0;
            padding: 12px 16px;
            border-radius: 10px;
            max-width: 80%;
            word-wrap: break-word;
        }
        .message.user {
            background: rgba(33,150,243,0.4);
            margin-left: auto;
            text-align: right;
        }
        .message.assistant {
            background: rgba(76,175,80,0.4);
            margin-right: auto;
        }
        .message.system {
            background: rgba(158,158,158,0.3);
            margin: 10px auto;
            text-align: center;
            font-style: italic;
            max-width: 90%;
        }
        
        .log {
            background: rgba(0,0,0,0.5);
            padding: 15px;
            border-radius: 10px;
            height: 250px;
            overflow-y: auto;
            font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
            font-size: 13px;
            white-space: pre-wrap;
            border: 1px solid rgba(255,255,255,0.1);
        }
        
        .feature-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 20px;
            margin: 30px 0;
        }
        
        .feature-card {
            background: rgba(255,255,255,0.1);
            padding: 25px;
            border-radius: 12px;
            text-align: center;
            transition: transform 0.3s ease;
        }
        .feature-card:hover { transform: translateY(-5px); }
        
        .emoji { font-size: 2.5em; margin-bottom: 15px; display: block; }
        
        .stats {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
            margin: 20px 0;
        }
        
        .stat-item {
            text-align: center;
            padding: 15px;
            background: rgba(255,255,255,0.1);
            border-radius: 8px;
        }
        
        .stat-value {
            font-size: 2em;
            font-weight: bold;
            display: block;
        }
        
        @media (max-width: 768px) {
            .container { padding: 20px; margin: 10px; }
            h1 { font-size: 2em; }
            .controls { grid-template-columns: 1fr; }
            .mic-button { width: 80px; height: 80px; font-size: 20px; }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎙️ LiveTalker Voice Assistant</h1>
        
        <div class="status-card" id="connectionStatus">
            <h3>🔗 Connection Status</h3>
            <div id="statusText">Click Connect to start</div>
        </div>
        
        <div class="controls">
            <button class="btn primary" onclick="connectWebSocket()">🔗 Connect</button>
            <button class="btn" onclick="requestMicrophone()" id="micPermBtn">🎤 Enable Microphone</button>
            <button class="btn" onclick="startListening()" id="startBtn" disabled>🎧 Start Listening</button>
            <button class="btn danger" onclick="stopListening()" id="stopBtn" disabled>🛑 Stop</button>
        </div>
        
        <div class="mic-section">
            <button class="mic-button" id="micButton" onclick="toggleListening()">🎤</button>
            <div>Click to toggle voice input</div>
        </div>
        
        <div class="vad-display">
            <h3>🎵 Voice Activity Detection</h3>
            <div class="vad-bar">
                <div class="vad-level" id="vadLevel"></div>
            </div>
            <div class="vad-text" id="vadStatus">Waiting for audio input...</div>
            
            <div class="stats">
                <div class="stat-item">
                    <span class="stat-value" id="audioChunks">0</span>
                    <div>Audio Chunks</div>
                </div>
                <div class="stat-item">
                    <span class="stat-value" id="speechDetected">0</span>
                    <div>Speech Events</div>
                </div>
                <div class="stat-item">
                    <span class="stat-value" id="avgConfidence">0%</span>
                    <div>Avg Confidence</div>
                </div>
            </div>
        </div>
        
        <div class="status-card" id="micStatus">
            <h3>🎤 Microphone Status</h3>
            <div id="micStatusText">Permission required</div>
        </div>
        
        <div class="conversation" id="conversation">
            <div class="message system">Welcome to LiveTalker! Enable microphone and start talking...</div>
        </div>
        
        <div class="status-card">
            <h3>📊 Activity Log</h3>
            <div id="log" class="log">Ready to start voice processing...</div>
        </div>
        
        <div class="feature-grid">
            <div class="feature-card">
                <span class="emoji">🎯</span>
                <h4>Real-Time VAD</h4>
                <p>Energy-based voice activity detection</p>
            </div>
            <div class="feature-card">
                <span class="emoji">⚡</span>
                <h4>Live Processing</h4>
                <p>Real-time audio stream analysis</p>
            </div>
            <div class="feature-card">
                <span class="emoji">🔄</span>
                <h4>Turn Detection</h4>
                <p>Intelligent conversation management</p>
            </div>
            <div class="feature-card">
                <span class="emoji">🌐</span>
                <h4>WebSocket</h4>
                <p>Low-latency bidirectional communication</p>
            </div>
        </div>
    </div>

    <script>
        let ws = null;
        let mediaStream = null;
        let audioContext = null;
        let processor = null;
        let isRecording = false;
        let connected = false;
        let stats = {
            audioChunks: 0,
            speechDetected: 0,
            totalConfidence: 0
        };
        
        function log(message) {
            const logDiv = document.getElementById('log');
            const timestamp = new Date().toLocaleTimeString();
            logDiv.textContent += `[${timestamp}] ${message}\\n`;
            logDiv.scrollTop = logDiv.scrollHeight;
        }
        
        function updateStatus(elementId, message, className = '') {
            const element = document.getElementById(elementId);
            if (element) {
                if (elementId === 'connectionStatus') {
                    document.getElementById('statusText').textContent = message;
                    element.className = 'status-card ' + className;
                } else {
                    element.textContent = message;
                }
            }
        }
        
        function addMessage(type, content) {
            const conversation = document.getElementById('conversation');
            const message = document.createElement('div');
            message.className = `message ${type}`;
            message.textContent = content;
            conversation.appendChild(message);
            conversation.scrollTop = conversation.scrollHeight;
        }
        
        function updateVAD(level, isActive) {
            const vadLevel = document.getElementById('vadLevel');
            const vadStatus = document.getElementById('vadStatus');
            const micButton = document.getElementById('micButton');
            
            vadLevel.style.width = `${level * 100}%`;
            
            if (isActive) {
                vadStatus.textContent = `🎵 Speech detected (${(level * 100).toFixed(1)}%)`;
                micButton.classList.add('recording');
            } else {
                vadStatus.textContent = `🔇 No speech (${(level * 100).toFixed(1)}%)`;
                micButton.classList.remove('recording');
            }
        }
        
        function updateStats() {
            document.getElementById('audioChunks').textContent = stats.audioChunks;
            document.getElementById('speechDetected').textContent = stats.speechDetected;
            const avgConf = stats.audioChunks > 0 ? (stats.totalConfidence / stats.audioChunks * 100).toFixed(0) : 0;
            document.getElementById('avgConfidence').textContent = avgConf + '%';
        }
        
        async function connectWebSocket() {
            const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
            const wsUrl = `${protocol}//${window.location.host}/media-stream`;
            
            log('Connecting to WebSocket...');
            updateStatus('connectionStatus', '🔄 Connecting...', '');
            
            try {
                ws = new WebSocket(wsUrl);
                
                ws.onopen = function() {
                    connected = true;
                    log('✅ WebSocket connected successfully');
                    updateStatus('connectionStatus', '✅ Connected and ready', 'active');
                };
                
                ws.onmessage = function(event) {
                    try {
                        const data = JSON.parse(event.data);
                        handleServerMessage(data);
                    } catch (e) {
                        log(`📨 Raw: ${event.data.substring(0, 100)}...`);
                    }
                };
                
                ws.onclose = function() {
                    connected = false;
                    log('❌ WebSocket disconnected');
                    updateStatus('connectionStatus', '❌ Disconnected', '');
                };
                
                ws.onerror = function(error) {
                    log(`❌ WebSocket error: ${error}`);
                    updateStatus('connectionStatus', '❌ Connection error', '');
                };
                
            } catch (error) {
                log(`❌ Failed to connect: ${error}`);
                updateStatus('connectionStatus', '❌ Connection failed', '');
            }
        }
        
        function handleServerMessage(data) {
            log(`📨 ${data.type}: ${JSON.stringify(data).substring(0, 100)}...`);
            
            switch(data.type) {
                case 'config':
                    addMessage('system', 'Server connected - voice processing ready!');
                    break;
                    
                case 'vad_result':
                    stats.audioChunks++;
                    stats.totalConfidence += data.confidence || 0;
                    if (data.is_speech) {
                        stats.speechDetected++;
                    }
                    updateVAD(data.confidence || 0, data.is_speech || false);
                    updateStats();
                    break;
                    
                case 'turn_detected':
                    log(`🔄 Turn: ${data.state}`);
                    break;
                    
                case 'speech_to_text':
                    if (data.text && data.text.trim()) {
                        addMessage('user', data.text);
                        log(`🗣️ You said: "${data.text}"`);
                    }
                    break;
                    
                case 'ai_response':
                    if (data.text) {
                        addMessage('assistant', data.text);
                        log(`🤖 AI: "${data.text.substring(0, 50)}..."`);
                    }
                    break;
                    
                case 'conversation_started':
                    addMessage('system', data.message || 'Conversation started');
                    updateStatus('connectionStatus', '🎧 Listening for voice...', 'listening');
                    break;
                    
                case 'error':
                    log(`❌ Error: ${data.error}`);
                    addMessage('system', `Error: ${data.error}`);
                    break;
                    
                default:
                    log(`📨 Unknown message type: ${data.type}`);
            }
        }
        
        async function requestMicrophone() {
            try {
                log('🎤 Requesting microphone permission...');
                updateStatus('micStatusText', '🔄 Requesting permission...');
                
                mediaStream = await navigator.mediaDevices.getUserMedia({
                    audio: {
                        sampleRate: 16000,
                        channelCount: 1,
                        echoCancellation: true,
                        noiseSuppression: true,
                        autoGainControl: true
                    }
                });
                
                log('✅ Microphone access granted');
                updateStatus('micStatusText', '✅ Microphone ready');
                
                // Setup Web Audio API
                audioContext = new (window.AudioContext || window.webkitAudioContext)({
                    sampleRate: 16000
                });
                
                const source = audioContext.createMediaStreamSource(mediaStream);
                
                // Create script processor for audio processing
                processor = audioContext.createScriptProcessor(1024, 1, 1);
                
                processor.onaudioprocess = function(event) {
                    if (isRecording && connected) {
                        const inputData = event.inputBuffer.getChannelData(0);
                        sendAudioData(inputData);
                    }
                };
                
                source.connect(processor);
                processor.connect(audioContext.destination);
                
                document.getElementById('startBtn').disabled = false;
                document.getElementById('micPermBtn').disabled = true;
                document.getElementById('micPermBtn').textContent = '✅ Mic Ready';
                
            } catch (error) {
                log(`❌ Microphone error: ${error.message}`);
                updateStatus('micStatusText', '❌ Permission denied');
                alert('Microphone access is required for voice input. Please allow microphone access and try again.');
            }
        }
        
        function sendAudioData(audioData) {
            if (!ws || ws.readyState !== WebSocket.OPEN) return;
            
            // Convert Float32Array to Int16Array for transmission
            const int16Array = new Int16Array(audioData.length);
            for (let i = 0; i < audioData.length; i++) {
                const clampedValue = Math.max(-1, Math.min(1, audioData[i]));
                int16Array[i] = clampedValue * 0x7FFF;
            }
            
            // Convert to base64
            const uint8Array = new Uint8Array(int16Array.buffer);
            const base64String = btoa(String.fromCharCode.apply(null, uint8Array));
            
            ws.send(JSON.stringify({
                type: 'audio',
                data: base64String,
                format: 'pcm_s16le',
                sample_rate: 16000,
                channels: 1
            }));
        }
        
        function startListening() {
            if (!connected) {
                alert('Please connect to WebSocket first');
                return;
            }
            if (!mediaStream) {
                alert('Please enable microphone first');
                return;
            }
            
            isRecording = true;
            log('🎧 Started listening for voice input...');
            updateStatus('connectionStatus', '🎧 Listening for voice...', 'listening');
            
            document.getElementById('startBtn').disabled = true;
            document.getElementById('stopBtn').disabled = false;
            document.getElementById('micButton').classList.add('recording');
            
            // Resume audio context if suspended
            if (audioContext && audioContext.state === 'suspended') {
                audioContext.resume();
            }
            
            // Send start message to server
            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.send(JSON.stringify({
                    type: 'start_conversation',
                    config: { 
                        personality: 'luna',
                        language: 'en'
                    }
                }));
            }
        }
        
        function stopListening() {
            isRecording = false;
            log('🛑 Stopped listening');
            updateStatus('connectionStatus', '✅ Connected (not listening)', 'active');
            
            document.getElementById('startBtn').disabled = false;
            document.getElementById('stopBtn').disabled = true;
            document.getElementById('micButton').classList.remove('recording');
            
            updateVAD(0, false);
            
            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.send(JSON.stringify({
                    type: 'stop_listening'
                }));
            }
        }
        
        function toggleListening() {
            if (isRecording) {
                stopListening();
            } else {
                startListening();
            }
        }
        
        // Auto-setup on page load
        document.addEventListener('DOMContentLoaded', function() {
            log('LiveTalker Voice Interface loaded');
            log('📝 Instructions:');
            log('1. Click "Connect" to establish WebSocket connection');
            log('2. Click "Enable Microphone" to request permissions');
            log('3. Click "Start Listening" to begin voice detection');
            log('4. Speak normally - VAD will detect your voice');
        });
        
        // Handle page unload
        window.addEventListener('beforeunload', function() {
            if (isRecording) {
                stopListening();
            }
            if (ws) {
                ws.close();
            }
        });
    </script>
</body>
</html>
    """
    return HTMLResponse(content=html_content)

@app.get("/health")
async def health_check():
    """Health check endpoint"""
    return {
        "status": "healthy",
        "timestamp": time.time(),
        "features": {
            "microphone_input": True,
            "simple_vad": True,
            "real_time_processing": True,
            "websocket_communication": True
        },
        "vad_method": "energy_based"
    }

@app.get("/stats")
async def get_stats():
    """System statistics"""
    return {
        "active_connections": len(active_connections),
        "processing_mode": "real_time",
        "vad_type": "simple_energy_based",
        "features": {
            "microphone_capture": "enabled",
            "audio_analysis": "real_time",
            "speech_detection": "active"
        }
    }

@app.websocket("/media-stream")
async def websocket_endpoint(websocket: WebSocket):
    """WebSocket endpoint for voice processing"""
    await websocket.accept()
    session_id = f"session_{int(time.time() * 1000)}"
    
    session = {
        "id": session_id,
        "websocket": websocket,
        "audio_buffer": [],
        "conversation": [],
        "is_listening": False,
        "speech_segments": [],
        "last_speech_time": 0
    }
    active_connections[session_id] = session
    
    logger.info(f"New voice session: {session_id}")
    
    try:
        # Send initial configuration
        await websocket.send_json({
            "type": "config",
            "session_id": session_id,
            "message": "Voice processing ready - simple VAD active",
            "vad_type": "energy_based"
        })
        
        async for message in websocket.iter_json():
            await handle_voice_message(session, message)
            
    except WebSocketDisconnect:
        logger.info(f"Voice session disconnected: {session_id}")
    except Exception as e:
        logger.error(f"Voice session error: {e}")
        try:
            await websocket.send_json({
                "type": "error",
                "error": str(e)
            })
        except:
            pass
    finally:
        if session_id in active_connections:
            del active_connections[session_id]

async def handle_voice_message(session: Dict, message: Dict[str, Any]):
    """Handle incoming voice messages"""
    msg_type = message.get("type")
    
    if msg_type == "start_conversation":
        session["is_listening"] = True
        await session["websocket"].send_json({
            "type": "conversation_started",
            "message": "Voice conversation started! Speak now and I'll detect your voice."
        })
        logger.info(f"Started voice conversation for {session['id']}")
        
    elif msg_type == "audio" and session["is_listening"]:
        await process_audio_chunk(session, message)
        
    elif msg_type == "stop_listening":
        session["is_listening"] = False
        await session["websocket"].send_json({
            "type": "stopped",
            "message": "Stopped listening for voice input"
        })

async def process_audio_chunk(session: Dict, message: Dict[str, Any]):
    """Process incoming audio with simple VAD"""
    try:
        # Decode base64 audio data
        audio_data = base64.b64decode(message["data"])
        
        # Convert PCM 16-bit to float
        audio_np = np.frombuffer(audio_data, dtype=np.int16).astype(np.float32) / 32768.0
        
        if len(audio_np) == 0:
            return
        
        # Apply simple VAD
        is_speech, confidence = simple_vad(audio_np, threshold=0.01)
        
        # Send VAD result to client
        await session["websocket"].send_json({
            "type": "vad_result",
            "is_speech": is_speech,
            "confidence": confidence,
            "timestamp": time.time(),
            "audio_length": len(audio_np)
        })
        
        # Accumulate speech segments
        if is_speech:
            session["audio_buffer"].extend(audio_np.tolist())
            session["last_speech_time"] = time.time()
            
            # If we have a significant amount of speech audio, process it
            if len(session["audio_buffer"]) > 16000:  # About 1 second at 16kHz
                await process_speech_segment(session)
                session["audio_buffer"] = []
        else:
            # If silence detected and we have accumulated audio, process it
            if (len(session["audio_buffer"]) > 8000 and  # At least 0.5 seconds
                time.time() - session["last_speech_time"] > 0.5):  # 0.5s silence
                await process_speech_segment(session)
                session["audio_buffer"] = []
        
    except Exception as e:
        logger.error(f"Error processing audio chunk: {e}")
        await session["websocket"].send_json({
            "type": "error",
            "error": f"Audio processing error: {str(e)}"
        })

async def process_speech_segment(session: Dict):
    """Process accumulated speech segment"""
    try:
        if len(session["audio_buffer"]) < 8000:  # Less than 0.5 seconds
            return
        
        duration = len(session["audio_buffer"]) / 16000  # Duration in seconds
        
        # For demonstration, create a simulated transcription
        simulated_text = f"Speech segment detected: {duration:.1f} seconds of audio"
        
        # Send speech-to-text result
        await session["websocket"].send_json({
            "type": "speech_to_text",
            "text": simulated_text,
            "confidence": 0.85,
            "duration": duration,
            "note": "This is simulated - in full implementation would use real STT"
        })
        
        # Add to conversation
        session["conversation"].append({
            "role": "user",
            "content": simulated_text,
            "timestamp": time.time(),
            "duration": duration
        })
        
        # Generate AI response (simulated)
        ai_response = f"I detected your {duration:.1f}-second speech segment! In the full CSM implementation, this would trigger ultra-low latency voice synthesis with 500ms response time."
        
        await session["websocket"].send_json({
            "type": "ai_response",
            "text": ai_response,
            "processing_info": {
                "input_duration": duration,
                "expected_ttfc": "500-650ms with CSM",
                "expected_rtf": "2.5x with optimizations"
            }
        })
        
        session["conversation"].append({
            "role": "assistant",
            "content": ai_response,
            "timestamp": time.time()
        })
        
        logger.info(f"Processed speech segment: {duration:.1f}s for session {session['id']}")
        
    except Exception as e:
        logger.error(f"Error processing speech segment: {e}")

if __name__ == "__main__":
    print("🎙️ Starting LiveTalker Simple Voice Server...")
    print("Features:")
    print("  ✅ Real microphone input capture")
    print("  ✅ Energy-based Voice Activity Detection")
    print("  ✅ Real-time audio processing")
    print("  ✅ WebSocket communication")
    print("  ✅ Speech segment detection")
    print("  ✅ Conversation flow simulation")
    print("")
    print("📍 Access URL: http://localhost:8000")
    print("🎯 Instructions:")
    print("  1. Open the URL in your browser")
    print("  2. Click 'Connect' to establish WebSocket") 
    print("  3. Click 'Enable Microphone' to request permissions")
    print("  4. Click 'Start Listening' to begin voice detection")
    print("  5. Speak normally - the system will detect your voice!")
    print("")
    
    uvicorn.run(
        app,
        host="0.0.0.0",
        port=8000,
        log_level="info"
    )