/**
 * Complete Integration Test for Multi-User Chrome MCP System
 * 
 * This test demonstrates the complete flow:
 * 1. Multiple Chrome extensions connect with unique user IDs
 * 2. Remote server automatically spawns LiveKit agents for each user
 * 3. Voice commands are routed to the correct Chrome extension
 * 4. Session isolation is maintained
 */

import WebSocket from 'ws';
import fetch from 'node-fetch';

const CHROME_WS_URL = 'ws://localhost:3001/chrome';
const MCP_HTTP_URL = 'http://localhost:3001/mcp';

class IntegratedUser {
  constructor(userNumber) {
    this.userNumber = userNumber;
    this.chromeUserId = `user_${Date.now()}_${userNumber}_${Math.random().toString(36).substring(2, 10)}`;
    this.ws = null;
    this.sessionInfo = null;
    this.receivedCommands = [];
    this.liveKitAgentExpected = false;
  }

  async connectChromeExtension() {
    return new Promise((resolve, reject) => {
      console.log(`\n🔌 [User ${this.userNumber}] Connecting Chrome extension...`);
      console.log(`   Generated User ID: ${this.chromeUserId}`);
      
      this.ws = new WebSocket(CHROME_WS_URL);

      this.ws.on('open', () => {
        console.log(`✅ [User ${this.userNumber}] Chrome WebSocket connected`);
        
        // Send connection info with unique user ID
        const connectionInfo = {
          type: 'connection_info',
          userId: this.chromeUserId,
          userAgent: `IntegratedTestUser-${this.userNumber}`,
          timestamp: Date.now(),
          extensionId: `integrated-test-${this.userNumber}`
        };

        this.ws.send(JSON.stringify(connectionInfo));
      });

      this.ws.on('message', (data) => {
        try {
          const message = JSON.parse(data.toString());
          
          if (message.type === 'session_info') {
            this.sessionInfo = message.sessionInfo;
            console.log(`🎯 [User ${this.userNumber}] Session established:`);
            console.log(`   Session ID: ${this.sessionInfo.sessionId}`);
            console.log(`   User ID: ${this.sessionInfo.userId}`);
            console.log(`   Expected LiveKit Room: mcp-chrome-user-${this.sessionInfo.userId}`);
            
            this.liveKitAgentExpected = true;
            resolve();
          }

          // Handle voice commands from LiveKit agent
          if (message.action === 'callTool') {
            this.receivedCommands.push({
              ...message,
              receivedAt: Date.now()
            });
            
            console.log(`🎤 [User ${this.userNumber}] Received voice command: ${message.params.name}`);
            console.log(`   Arguments:`, message.params.arguments);
            
            // Simulate Chrome extension executing the command
            const response = {
              id: message.id,
              success: true,
              result: {
                message: `Command ${message.params.name} executed successfully`,
                executedBy: `ChromeExtension-User${this.userNumber}`,
                userId: this.chromeUserId,
                timestamp: Date.now()
              }
            };
            
            this.ws.send(JSON.stringify(response));
            console.log(`📤 [User ${this.userNumber}] Sent command response`);
          }

        } catch (error) {
          console.error(`❌ [User ${this.userNumber}] Error parsing message:`, error);
        }
      });

      this.ws.on('error', (error) => {
        console.error(`❌ [User ${this.userNumber}] WebSocket error:`, error);
        reject(error);
      });

      setTimeout(() => {
        if (!this.sessionInfo) {
          reject(new Error(`[User ${this.userNumber}] Timeout waiting for session info`));
        }
      }, 10000);
    });
  }

  async simulateVoiceCommand(toolName, args) {
    console.log(`🎙️ [User ${this.userNumber}] Simulating voice command: ${toolName}`);
    
    const payload = {
      jsonrpc: '2.0',
      id: `voice_${this.userNumber}_${Date.now()}`,
      method: 'tools/call',
      params: {
        name: toolName,
        arguments: {
          ...args,
          userContext: this.chromeUserId
        }
      }
    };

    const headers = {
      'Content-Type': 'application/json',
      'chrome-user-id': this.chromeUserId, // Route to this specific user
      'user-agent': `LiveKitAgent-User${this.userNumber}`
    };

    try {
      const response = await fetch(MCP_HTTP_URL, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(payload)
      });

      const result = await response.json();
      console.log(`📨 [User ${this.userNumber}] Voice command response:`, result.result || result.error);
      return result;
    } catch (error) {
      console.error(`❌ [User ${this.userNumber}] Error sending voice command:`, error);
      throw error;
    }
  }

  getStatus() {
    return {
      userNumber: this.userNumber,
      chromeUserId: this.chromeUserId,
      sessionId: this.sessionInfo?.sessionId,
      liveKitAgentExpected: this.liveKitAgentExpected,
      commandsReceived: this.receivedCommands.length,
      lastCommand: this.receivedCommands[this.receivedCommands.length - 1]?.params?.name
    };
  }

  disconnect() {
    if (this.ws) {
      console.log(`👋 [User ${this.userNumber}] Disconnecting Chrome extension`);
      this.ws.close();
    }
  }
}

async function runCompleteIntegrationTest() {
  console.log('🚀 COMPLETE INTEGRATION TEST FOR MULTI-USER CHROME MCP SYSTEM');
  console.log('=' .repeat(80));
  console.log('This test demonstrates:');
  console.log('✓ Multiple Chrome extensions with unique user IDs');
  console.log('✓ Automatic LiveKit agent spawning');
  console.log('✓ Voice command routing with session isolation');
  console.log('✓ End-to-end user experience');
  console.log('=' .repeat(80));

  const users = [];
  const NUM_USERS = 3;

  try {
    // Phase 1: Connect Chrome Extensions
    console.log('\n📋 PHASE 1: Chrome Extension Connections');
    console.log('-' .repeat(50));

    for (let i = 1; i <= NUM_USERS; i++) {
      const user = new IntegratedUser(i);
      users.push(user);
      
      await user.connectChromeExtension();
      console.log(`✅ User ${i} Chrome extension connected successfully`);
      
      // Wait between connections to see the flow clearly
      await new Promise(resolve => setTimeout(resolve, 2000));
    }

    // Phase 2: Verify LiveKit Agent Spawning
    console.log('\n📋 PHASE 2: LiveKit Agent Verification');
    console.log('-' .repeat(50));
    
    console.log('⏳ Waiting for LiveKit agents to start...');
    await new Promise(resolve => setTimeout(resolve, 5000));
    
    users.forEach(user => {
      const status = user.getStatus();
      console.log(`🤖 User ${status.userNumber}: LiveKit agent expected for room mcp-chrome-user-${status.chromeUserId}`);
    });

    // Phase 3: Test Voice Commands
    console.log('\n📋 PHASE 3: Voice Command Testing');
    console.log('-' .repeat(50));

    const voiceCommands = [
      { tool: 'chrome_navigate', args: { url: 'https://www.google.com' } },
      { tool: 'chrome_click_element', args: { selector: '#search-button' } },
      { tool: 'chrome_get_web_content', args: { selector: 'body' } }
    ];

    for (let i = 0; i < users.length; i++) {
      const user = users[i];
      const command = voiceCommands[i % voiceCommands.length];
      
      console.log(`\n🎤 Testing voice command for User ${user.userNumber}:`);
      console.log(`   Command: ${command.tool}`);
      console.log(`   Target: ${command.args.url || command.args.selector || 'page content'}`);
      
      await user.simulateVoiceCommand(command.tool, command.args);
      
      // Wait for command to be processed
      await new Promise(resolve => setTimeout(resolve, 3000));
    }

    // Phase 4: Test Session Isolation
    console.log('\n📋 PHASE 4: Session Isolation Testing');
    console.log('-' .repeat(50));

    console.log('🔒 Testing that commands only go to the intended user...');
    
    // Send a command from User 1 that should only affect User 1
    await users[0].simulateVoiceCommand('chrome_navigate', { 
      url: 'https://example.com/isolation-test',
      testId: 'isolation-test-user-1'
    });

    await new Promise(resolve => setTimeout(resolve, 2000));

    // Phase 5: Results Analysis
    console.log('\n📋 PHASE 5: Results Analysis');
    console.log('-' .repeat(50));

    let totalCommandsSent = NUM_USERS + 1; // 3 initial commands + 1 isolation test
    let totalCommandsReceived = 0;
    let isolationSuccess = true;

    console.log('\n📊 USER STATUS REPORT:');
    users.forEach(user => {
      const status = user.getStatus();
      totalCommandsReceived += status.commandsReceived;
      
      console.log(`\n👤 User ${status.userNumber}:`);
      console.log(`   Chrome User ID: ${status.chromeUserId}`);
      console.log(`   Session ID: ${status.sessionId}`);
      console.log(`   Commands Received: ${status.commandsReceived}`);
      console.log(`   Last Command: ${status.lastCommand || 'None'}`);
      console.log(`   LiveKit Agent Expected: ${status.liveKitAgentExpected ? '✅' : '❌'}`);
    });

    // Check isolation: User 1 should have received 2 commands, others should have 1 each
    const user1Commands = users[0].getStatus().commandsReceived;
    const user2Commands = users[1].getStatus().commandsReceived;
    const user3Commands = users[2].getStatus().commandsReceived;

    if (user1Commands !== 2 || user2Commands !== 1 || user3Commands !== 1) {
      isolationSuccess = false;
    }

    // Final Results
    console.log('\n🎯 FINAL RESULTS:');
    console.log('=' .repeat(50));
    console.log(`📤 Total Commands Sent: ${totalCommandsSent}`);
    console.log(`📥 Total Commands Received: ${totalCommandsReceived}`);
    console.log(`🎯 Command Routing: ${totalCommandsReceived === totalCommandsSent ? '✅ SUCCESS' : '❌ FAILED'}`);
    console.log(`🔒 Session Isolation: ${isolationSuccess ? '✅ SUCCESS' : '❌ FAILED'}`);
    console.log(`🤖 LiveKit Agents: ${users.every(u => u.liveKitAgentExpected) ? '✅ ALL EXPECTED' : '❌ SOME MISSING'}`);

    if (totalCommandsReceived === totalCommandsSent && isolationSuccess) {
      console.log('\n🎉 COMPLETE INTEGRATION TEST PASSED! 🎉');
      console.log('✅ Multi-user Chrome MCP system is working correctly');
    } else {
      console.log('\n❌ COMPLETE INTEGRATION TEST FAILED!');
      console.log('❌ Issues detected in multi-user system');
    }

  } catch (error) {
    console.error('\n❌ Integration test failed:', error);
  } finally {
    // Cleanup
    console.log('\n🧹 Cleaning up test connections...');
    users.forEach(user => user.disconnect());
    
    setTimeout(() => {
      console.log('✅ Integration test completed');
      process.exit(0);
    }, 3000);
  }
}

// Run the complete integration test
runCompleteIntegrationTest().catch(console.error);
