import { test, chromium } from '@playwright/test';
import * as fs from 'fs';
import * as path from 'path';

/**
 * This test captures the complete network traffic (HAR file) for the "Join Session" flow
 * from the legacy JamKazam application. The captured data will be used to:
 * 1. Document all API calls to /api/*
 * 2. Document all WebSocket messages
 * 3. Create a migration test plan for the new jam-ui interface
 */
test('Capture network traffic for joining a music session', async () => {
  // Launch browser with ability to capture network traffic
  const browser = await chromium.launch({
    headless: false, // Use headed mode to see what's happening
    slowMo: 1000, // Slow down by 1 second to make actions visible
  });

  const context = await browser.newContext({
    ignoreHTTPSErrors: true,
    recordHar: {
      path: path.join(__dirname, '../test-results/session-join-flow.har'),
      mode: 'full', // Capture full request/response bodies
    },
  });

  const page = await context.newPage();

  // Array to collect all WebSocket messages
  const wsMessages: any[] = [];
  const apiCalls: any[] = [];

  // Listen to all network requests
  page.on('request', request => {
    const url = request.url();
    if (url.includes('/api/')) {
      console.log(`API REQUEST: ${request.method()} ${url}`);
      apiCalls.push({
        type: 'request',
        method: request.method(),
        url: url,
        headers: request.headers(),
        timestamp: new Date().toISOString(),
      });
    }
  });

  page.on('response', async response => {
    const url = response.url();
    if (url.includes('/api/')) {
      console.log(`API RESPONSE: ${response.status()} ${url}`);
      let body = null;
      try {
        body = await response.text();
      } catch (e) {
        // Some responses can't be read
      }
      apiCalls.push({
        type: 'response',
        status: response.status(),
        url: url,
        headers: response.headers(),
        body: body,
        timestamp: new Date().toISOString(),
      });
    }
  });

  // Listen to WebSocket events
  page.on('websocket', ws => {
    console.log(`WebSocket opened: ${ws.url()}`);
    wsMessages.push({
      type: 'websocket-open',
      url: ws.url(),
      timestamp: new Date().toISOString(),
    });

    ws.on('framesent', frame => {
      console.log(`WS SENT: ${frame.payload}`);
      wsMessages.push({
        type: 'sent',
        payload: frame.payload,
        timestamp: new Date().toISOString(),
      });
    });

    ws.on('framereceived', frame => {
      console.log(`WS RECEIVED: ${frame.payload}`);
      wsMessages.push({
        type: 'received',
        payload: frame.payload,
        timestamp: new Date().toISOString(),
      });
    });

    ws.on('close', () => {
      console.log('WebSocket closed');
      wsMessages.push({
        type: 'websocket-close',
        timestamp: new Date().toISOString(),
      });
    });
  });

  try {
    console.log('Step 1: Navigate to signin page');
    await page.goto('http://www.jamkazam.com:3000/signin', {
      waitUntil: 'networkidle',
      timeout: 30000,
    });

    console.log('Step 2: Login with credentials');
    // Fill in login form
    await page.fill('input[name="email"], input[type="email"]', 'nuwan@jamkazam.com');
    await page.fill('input[name="password"], input[type="password"]', 'jam123');

    // Click sign in button
    await page.click('button[type="submit"], input[type="submit"], button:has-text("Sign in"), button:has-text("Login")');

    // Wait for navigation after login
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(2000);

    console.log('Step 3: Click "create session" tile');
    // Look for create session button/tile
    await page.click('[data-testid="create-session"], button:has-text("Create Session"), a:has-text("Create Session")');
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(2000);

    console.log('Step 4: Press Control+Shift+0 to trick browser as native client');
    await page.keyboard.press('Control+Shift+Digit0');
    await page.waitForTimeout(1000);

    console.log('Step 5: Click "create quick start" button');
    await page.click('button:has-text("Create Quick Start"), button:has-text("Quick Start")');

    // Wait for session to load
    await page.waitForLoadState('networkidle');
    await page.waitForTimeout(5000); // Give time for WebSocket messages

    console.log('Recording complete. Saving captured data...');

    // Save API calls to a separate JSON file
    const apiCallsPath = path.join(__dirname, '../test-results/api-calls.json');
    fs.writeFileSync(apiCallsPath, JSON.stringify(apiCalls, null, 2));
    console.log(`API calls saved to: ${apiCallsPath}`);

    // Save WebSocket messages to a separate JSON file
    const wsMessagesPath = path.join(__dirname, '../test-results/websocket-messages.json');
    fs.writeFileSync(wsMessagesPath, JSON.stringify(wsMessages, null, 2));
    console.log(`WebSocket messages saved to: ${wsMessagesPath}`);

    // Keep browser open for manual inspection
    console.log('Keeping browser open for 30 seconds for manual inspection...');
    await page.waitForTimeout(30000);

  } catch (error) {
    console.error('Error during test:', error);
    throw error;
  } finally {
    // Close context to save HAR file
    await context.close();
    await browser.close();
  }
});
