import { test, expect } from '@playwright/test';
import { APIInterceptor } from '../utils/api-interceptor';
import { compareAPISequences } from '../utils/sequence-comparator';
import { loginToJamUI, navigateToSessionCreation, fillSessionForm, waitForAPICalls } from '../utils/test-helpers';
import * as fs from 'fs';
import * as path from 'path';

test.describe('Session Creation API Verification', () => {
  test('session creation makes all required API calls', async ({ page }) => {
    const apiInterceptor = new APIInterceptor();
    apiInterceptor.intercept(page);

    // Login first
    await loginToJamUI(page);
    await waitForAPICalls(page);

    // Clear captured calls from login
    apiInterceptor.reset();

    // Navigate to session creation and fill form (jam-ui approach)
    await navigateToSessionCreation(page);
    await waitForAPICalls(page);

    // Fill and submit session creation form
    await fillSessionForm(page, { sessionType: 'private' });
    await waitForAPICalls(page, 5000);

    // Get captured calls
    const actualCalls = apiInterceptor.getCalls();

    // Load expected sequence (Step 5 from verification)
    const expectedPath = path.join(__dirname, '../fixtures/legacy-sequences/session-creation-simplified.json');
    const expectedCalls = JSON.parse(fs.readFileSync(expectedPath, 'utf8'));

    console.log(`\nSession Creation API Verification:`);
    console.log(`  Actual calls: ${actualCalls.length}`);
    console.log(`  Expected calls: ${expectedCalls.length}`);

    // Compare sequences
    const comparison = compareAPISequences(actualCalls, expectedCalls);

    // Log comparison report
    console.log('\n' + comparison.report);

    // Save results
    const resultsDir = path.join(__dirname, '../test-results/api-verification');
    if (!fs.existsSync(resultsDir)) {
      fs.mkdirSync(resultsDir, { recursive: true });
    }

    fs.writeFileSync(
      path.join(resultsDir, 'session-creation-actual-calls.json'),
      JSON.stringify(actualCalls, null, 2)
    );

    fs.writeFileSync(
      path.join(resultsDir, 'session-creation-comparison-report.md'),
      comparison.report
    );

    // Critical session creation endpoints
    const endpoints = apiInterceptor.getUniqueEndpoints();

    // Must have session creation
    expect(endpoints.some(e => e.includes('POST /api/sessions'))).toBe(true);

    // Check match percentage
    const matchPercentage = (comparison.matchedCalls / comparison.totalCalls) * 100;
    console.log(`\nMatch percentage: ${matchPercentage.toFixed(1)}%`);

    // We expect at least 70% match (allowing for some differences)
    expect(matchPercentage).toBeGreaterThanOrEqual(70);
  });

  test('session creation sequence includes critical endpoints', async ({ page }) => {
    const apiInterceptor = new APIInterceptor();
    apiInterceptor.intercept(page);

    await loginToJamUI(page);
    await waitForAPICalls(page);
    apiInterceptor.reset();

    await navigateToSessionCreation(page);
    await waitForAPICalls(page);
    await fillSessionForm(page);
    await waitForAPICalls(page, 5000);

    const calls = apiInterceptor.getCalls();

    // Find critical session endpoints
    const sessionCreation = calls.find(c =>
      c.method === 'POST' && c.pathname.match(/\/api\/sessions\/?$/)
    );

    const participantAdd = calls.find(c =>
      c.method === 'POST' && c.pathname.includes('/participants')
    );

    const sessionHistory = calls.find(c =>
      c.method === 'GET' && c.pathname.includes('/history')
    );

    const sessionGet = calls.find(c =>
      c.method === 'GET' && c.pathname.match(/\/api\/sessions\/[a-f0-9-]+\/?$/)
    );

    const tracksUpdate = calls.find(c =>
      c.method === 'PUT' && c.pathname.includes('/tracks')
    );

    const sessionChat = calls.find(c =>
      c.method === 'GET' &&
      c.pathname.includes('/chat') &&
      c.url.includes('music_session')
    );

    const udpReachable = calls.find(c =>
      c.method === 'POST' && c.pathname.includes('/udp_reachable')
    );

    console.log('\nCritical session endpoints found:');
    console.log(`  ✓ POST /api/sessions: ${sessionCreation ? 'YES' : 'NO'}`);
    console.log(`  ✓ POST /api/sessions/{id}/participants: ${participantAdd ? 'YES' : 'NO'}`);
    console.log(`  ✓ GET /api/sessions/{id}/history: ${sessionHistory ? 'YES' : 'NO'}`);
    console.log(`  ✓ GET /api/sessions/{id}: ${sessionGet ? 'YES' : 'NO'}`);
    console.log(`  ✓ PUT /api/sessions/{id}/tracks: ${tracksUpdate ? 'YES' : 'NO'}`);
    console.log(`  ✓ GET /api/chat?...music_session=: ${sessionChat ? 'YES' : 'NO'}`);
    console.log(`  ✓ POST /api/users/{id}/udp_reachable: ${udpReachable ? 'YES' : 'NO'}`);

    // All critical endpoints should be present
    expect(sessionCreation).toBeDefined();
    expect(participantAdd).toBeDefined();
    expect(sessionHistory).toBeDefined();
    expect(sessionGet).toBeDefined();
    expect(tracksUpdate).toBeDefined();
    expect(udpReachable).toBeDefined();
  });

  test('session is created with valid session ID', async ({ page }) => {
    const apiInterceptor = new APIInterceptor();
    apiInterceptor.intercept(page);

    await loginToJamUI(page);
    await waitForAPICalls(page);
    apiInterceptor.reset();

    await navigateToSessionCreation(page);
    await waitForAPICalls(page);
    await fillSessionForm(page);
    await waitForAPICalls(page, 5000);

    const calls = apiInterceptor.getCalls();

    // Find the POST /api/sessions call
    const sessionCreation = calls.find(c =>
      c.method === 'POST' && c.pathname.match(/\/api\/sessions\/?$/)
    );

    expect(sessionCreation).toBeDefined();

    // Check if response contains session ID
    if (sessionCreation?.responseBody) {
      const sessionId = sessionCreation.responseBody.id || sessionCreation.responseBody.session_id;

      console.log(`\nSession created with ID: ${sessionId}`);

      // Verify it's a valid UUID
      expect(sessionId).toMatch(/^[a-f0-9-]{36}$/i);

      // Verify subsequent calls use this session ID
      const sessionSpecificCalls = calls.filter(c =>
        c.pathname.includes(sessionId)
      );

      console.log(`Subsequent calls using session ID: ${sessionSpecificCalls.length}`);
      expect(sessionSpecificCalls.length).toBeGreaterThan(0);
    }
  });

  test('session form loads reference data', async ({ page }) => {
    const apiInterceptor = new APIInterceptor();
    apiInterceptor.intercept(page);

    await loginToJamUI(page);
    await waitForAPICalls(page);
    apiInterceptor.reset();

    await navigateToSessionCreation(page);
    await waitForAPICalls(page, 3000);

    const calls = apiInterceptor.getCalls();

    // Check what reference data is loaded for the session creation form
    const genres = calls.filter(c => c.pathname.includes('/api/genres'));
    const instruments = calls.filter(c => c.pathname.includes('/api/instruments'));
    const friends = calls.filter(c => c.pathname.includes('/friends'));

    console.log('\nSession form API calls:');
    console.log(`  /api/genres: ${genres.length} calls`);
    console.log(`  /api/instruments: ${instruments.length} calls`);
    console.log(`  /api/users/{id}/friends: ${friends.length} calls`);

    // jam-ui may load reference data differently than legacy
    // Just verify the page loaded successfully
    expect(calls.length).toBeGreaterThan(0);
  });
});
