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

test.describe('Login API Verification', () => {
  test('jam-ui login makes same API calls as legacy app', async ({ page }) => {
    const apiInterceptor = new APIInterceptor();
    apiInterceptor.intercept(page);

    // Perform login
    await loginToJamUI(page, {
      email: 'nuwan@jamkazam.com',
      password: 'jam123',
    });

    await waitForAPICalls(page, 5000);

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

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

    console.log(`\nLogin 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, 'login-actual-calls.json'),
      JSON.stringify(actualCalls, null, 2)
    );

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

    // Assert that we have critical login endpoints
    const endpoints = apiInterceptor.getUniqueEndpoints();

    // Critical endpoints that MUST be present
    expect(endpoints.some(e => e.includes('/api/users/'))).toBe(true);
    expect(endpoints.some(e => e.includes('/api/genres'))).toBe(true);
    expect(endpoints.some(e => e.includes('/api/countries'))).toBe(true);

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

    // We expect at least 80% match for login flow
    expect(matchPercentage).toBeGreaterThanOrEqual(80);
  });

  test('login API calls are in correct order', async ({ page }) => {
    const apiInterceptor = new APIInterceptor();
    apiInterceptor.intercept(page);

    await loginToJamUI(page);
    await waitForAPICalls(page);

    const actualCalls = apiInterceptor.getCalls();
    const expectedPath = path.join(__dirname, '../fixtures/legacy-sequences/login-simplified.json');
    const expectedCalls = JSON.parse(fs.readFileSync(expectedPath, 'utf8'));

    const comparison = compareAPISequences(actualCalls, expectedCalls);

    // Check for significant order issues
    if (comparison.outOfOrderCalls.length > 0) {
      console.log('\nOut of order calls detected:');
      for (const order of comparison.outOfOrderCalls) {
        console.log(`  ${order.endpoint}: deviation of ${order.deviation} positions`);
      }
    }

    // Allow some flexibility in ordering, but not too much
    const maxDeviationAllowed = 5;
    const significantDeviations = comparison.outOfOrderCalls.filter(
      o => o.deviation > maxDeviationAllowed
    );

    expect(significantDeviations.length).toBe(0);
  });

  test('login makes POST request to create session', async ({ page }) => {
    const apiInterceptor = new APIInterceptor();
    apiInterceptor.intercept(page);

    await loginToJamUI(page);
    await waitForAPICalls(page);

    const postCalls = apiInterceptor.getCallsByMethod('POST');

    // Should have POST to /api/sessions or similar login endpoint
    const sessionPost = postCalls.find(call =>
      call.pathname.includes('/api/session') ||
      call.pathname.includes('/api/auth') ||
      call.pathname.includes('/api/login')
    );

    // Note: Legacy app uses Rails sessions, so this might not be present
    // Just log what we find
    console.log('\nPOST calls during login:');
    postCalls.forEach(call => {
      console.log(`  ${call.method} ${call.pathname}`);
    });
  });

  test('login retrieves user data', async ({ page }) => {
    const apiInterceptor = new APIInterceptor();
    apiInterceptor.intercept(page);

    await loginToJamUI(page);
    await waitForAPICalls(page);

    const userCalls = apiInterceptor.getCallsByPath('/api/users/');

    expect(userCalls.length).toBeGreaterThan(0);

    // Should have successful response
    const successfulUserCall = userCalls.find(call =>
      call.responseStatus && call.responseStatus >= 200 && call.responseStatus < 300
    );

    expect(successfulUserCall).toBeDefined();

    if (successfulUserCall?.responseBody) {
      console.log('\nUser data received:');
      console.log(`  User ID: ${successfulUserCall.responseBody.id || 'N/A'}`);
      console.log(`  Email: ${successfulUserCall.responseBody.email || 'N/A'}`);
    }
  });
});
