#!/usr/bin/env python3
"""
Test Client for Voice Agent Validation System

Simulates a phone call by sending text that gets converted to speech,
then sending that speech to the agent.

Usage:
    python test_client.py

Then type Vietnamese text to simulate what the user would say.
"""

import asyncio
import websockets
import wave
import struct
import numpy as np
from loguru import logger

# Simple text-to-audio mock for testing (sends silence)
def text_to_mock_audio(text: str, duration: float = 2.0, sample_rate: int = 16000) -> bytes:
    """
    Create mock audio data for testing
    In production, this would be real audio from microphone
    """
    num_samples = int(duration * sample_rate)
    # Generate silence (you could add white noise if needed)
    audio_array = np.zeros(num_samples, dtype=np.int16)
    return audio_array.tobytes()


async def test_conversation():
    """Run a test conversation"""
    uri = "ws://localhost:8765"
    
    print("=" * 70)
    print("Voice Agent Test Client")
    print("=" * 70)
    print(f"Connecting to: {uri}")
    print()
    
    try:
        async with websockets.connect(uri) as websocket:
            print("✅ Connected!")
            print()
            print("Instructions:")
            print("  - Type what the user would say (in Vietnamese)")
            print("  - The agent will process and respond")
            print("  - Type 'quit' to exit")
            print()
            print("-" * 70)
            
            # Receive welcome message
            try:
                welcome_audio = await asyncio.wait_for(websocket.recv(), timeout=5.0)
                print("🤖 Agent: [Welcome message received]")
                print()
            except asyncio.TimeoutError:
                print("⚠️  No welcome message (timeout)")
                print()
            
            # Conversation loop
            turn = 1
            while True:
                # Get user input
                print(f"Turn {turn}")
                user_input = input("👤 You (text): ").strip()
                
                if user_input.lower() in ['quit', 'exit', 'q']:
                    print("\nGoodbye!")
                    break
                
                if not user_input:
                    continue
                
                # Convert to mock audio (5 seconds)
                print(f"   📤 Sending audio... (simulating: '{user_input}')")
                mock_audio = text_to_mock_audio(user_input, duration=5.0)
                
                await websocket.send(mock_audio)
                
                # Wait for response
                try:
                    response_audio = await asyncio.wait_for(websocket.recv(), timeout=10.0)
                    print(f"   📥 Received response audio ({len(response_audio)} bytes)")
                    print(f"🤖 Agent: [Response synthesized - would be played here]")
                    print()
                except asyncio.TimeoutError:
                    print("   ⚠️  No response (timeout)")
                    print()
                
                turn += 1
    
    except ConnectionRefusedError:
        print("❌ Connection refused. Is the agent running?")
        print("   Start it with: python voice_agent_validation.py")
    except Exception as e:
        print(f"❌ Error: {e}")
        import traceback
        traceback.print_exc()


async def test_scenarios():
    """
    Run automated test scenarios
    """
    uri = "ws://localhost:8765"
    
    scenarios = [
        {
            "name": "Existing Customer (Verified)",
            "inputs": [
                "Số tôi là 0901234567",
                "Đúng",
                "Tôi là Nguyễn Văn An",
                "Vâng"
            ]
        },
        {
            "name": "New Customer",
            "inputs": [
                "0999888777",
                "Đúng",
                "Nguyễn Thị Mai",
                "Đúng"
            ]
        },
        {
            "name": "Existing Customer (Name Mismatch)",
            "inputs": [
                "0901234567",
                "Đúng",
                "Trần Văn Bình",
                "Có"
            ]
        }
    ]
    
    print("=" * 70)
    print("Automated Test Scenarios")
    print("=" * 70)
    print()
    
    for i, scenario in enumerate(scenarios, 1):
        print(f"Scenario {i}: {scenario['name']}")
        print("-" * 70)
        
        try:
            async with websockets.connect(uri) as websocket:
                # Receive welcome
                await asyncio.wait_for(websocket.recv(), timeout=5.0)
                print("🤖 [Welcome received]")
                
                # Send inputs
                for j, user_input in enumerate(scenario['inputs'], 1):
                    print(f"\nTurn {j}: '{user_input}'")
                    
                    # Send mock audio
                    mock_audio = text_to_mock_audio(user_input, duration=5.0)
                    await websocket.send(mock_audio)
                    
                    # Receive response
                    try:
                        response = await asyncio.wait_for(websocket.recv(), timeout=10.0)
                        print(f"🤖 [Response received: {len(response)} bytes]")
                    except asyncio.TimeoutError:
                        print("⚠️  [No response]")
                        break
                
                print()
                print("✅ Scenario complete")
                print()
        
        except Exception as e:
            print(f"❌ Scenario failed: {e}")
            print()
        
        # Wait between scenarios
        if i < len(scenarios):
            await asyncio.sleep(2)
    
    print("=" * 70)
    print("All scenarios complete")
    print("=" * 70)


def main():
    """Main entry point"""
    import sys
    
    if len(sys.argv) > 1 and sys.argv[1] == "auto":
        print("Running automated test scenarios...")
        print()
        asyncio.run(test_scenarios())
    else:
        print("Running interactive test client...")
        print()
        asyncio.run(test_conversation())


if __name__ == "__main__":
    main()
