import { test, expect } from '@playwright/test';

/**
 * API Response Time Benchmarks
 * Tests all critical API endpoints for performance
 */

test.describe('API Response Times - Health & Status', () => {
  test('Health check is very fast (< 100ms)', async ({ request }) => {
    const startTime = Date.now();
    const response = await request.get('http://localhost:9000/api/health');
    const responseTime = Date.now() - startTime;

    console.log(`/api/health response time: ${responseTime}ms`);

    expect(response.ok()).toBeTruthy();
    expect(responseTime).toBeLessThan(100);
  });

  test('Status endpoint performance', async ({ request }) => {
    const startTime = Date.now();
    const response = await request.get('http://localhost:9000/api/status');
    const responseTime = Date.now() - startTime;

    console.log(`/api/status response time: ${responseTime}ms`);

    expect(response.status()).toBeLessThan(500);
    expect(responseTime).toBeLessThan(500);
  });
});

test.describe('API Response Times - Authentication', () => {
  const testEmail = `perf-test-${Date.now()}@example.com`;

  test('User registration completes within 1 second', async ({ request }) => {
    const startTime = Date.now();

    const response = await request.post('http://localhost:9000/api/register', {
      data: {
        email: testEmail,
        password: 'SecurePassword123!',
        fullName: 'Performance Test User',
      },
      headers: {
        'Content-Type': 'application/json',
      },
    });

    const responseTime = Date.now() - startTime;

    console.log(`/api/register response time: ${responseTime}ms`);
    console.log(`Registration status: ${response.status()}`);

    // Should complete within 1s
    expect(responseTime).toBeLessThan(1000);

    // Log if it's rate limited (expected after first few requests)
    if (response.status() === 429) {
      console.log('⚠️ Rate limited (expected behavior)');
    }
  });

  test('Send OTP is fast (< 600ms)', async ({ request }) => {
    const startTime = Date.now();

    const response = await request.post('http://localhost:9000/api/send-otp', {
      data: {
        email: `otp-test-${Date.now()}@example.com`,
        language: 'en',
      },
      headers: {
        'Content-Type': 'application/json',
      },
    });

    const responseTime = Date.now() - startTime;

    console.log(`/api/send-otp response time: ${responseTime}ms`);
    console.log(`Send OTP status: ${response.status()}`);

    // Should complete within 600ms
    expect(responseTime).toBeLessThan(600);
  });

  test('Login endpoint performance', async ({ request }) => {
    // First create a user
    const loginEmail = `login-perf-${Date.now()}@example.com`;
    await request.post('http://localhost:9000/api/register', {
      data: {
        email: loginEmail,
        password: 'SecurePassword123!',
        fullName: 'Login Test',
      },
    });

    // Wait a bit for rate limiter
    await new Promise(resolve => setTimeout(resolve, 1000));

    // Now test login performance
    const startTime = Date.now();

    const response = await request.post('http://localhost:9000/api/auth/login', {
      data: {
        email: loginEmail,
        password: 'SecurePassword123!',
      },
      headers: {
        'Content-Type': 'application/json',
      },
    });

    const responseTime = Date.now() - startTime;

    console.log(`/api/auth/login response time: ${responseTime}ms`);
    console.log(`Login status: ${response.status()}`);

    // Should complete within 800ms
    expect(responseTime).toBeLessThan(800);
  });
});

test.describe('API Response Times - Demo Booking', () => {
  test('Demo booking submission (< 1200ms)', async ({ request }) => {
    const startTime = Date.now();

    const response = await request.post('http://localhost:9000/api/demo-book', {
      data: {
        name: 'Performance Test',
        email: `demo-perf-${Date.now()}@example.com`,
        phone: '+971501234567',
        date: '2024-12-20',
        time: '10:00 AM',
        companyName: 'Test Clinic',
        language: 'en',
      },
      headers: {
        'Content-Type': 'application/json',
      },
    });

    const responseTime = Date.now() - startTime;

    console.log(`/api/demo-book response time: ${responseTime}ms`);
    console.log(`Demo booking status: ${response.status()}`);

    // Should complete within 1200ms
    expect(responseTime).toBeLessThan(1200);
  });
});

test.describe('API Response Times - Concurrent Requests', () => {
  test('Health check handles 20 concurrent requests efficiently', async ({ request }) => {
    const concurrentRequests = 20;
    const startTime = Date.now();

    const promises = Array.from({ length: concurrentRequests }, () =>
      request.get('http://localhost:9000/api/health')
    );

    const responses = await Promise.all(promises);
    const totalTime = Date.now() - startTime;
    const avgTime = totalTime / concurrentRequests;

    console.log(`20 concurrent /api/health requests:`);
    console.log(`Total time: ${totalTime}ms`);
    console.log(`Average time: ${avgTime.toFixed(2)}ms`);
    console.log(`All successful: ${responses.every(r => r.ok())}`);

    // All should succeed
    expect(responses.every(r => r.ok())).toBeTruthy();

    // Average response time should be reasonable
    expect(avgTime).toBeLessThan(200);
  });

  test('Status endpoint handles 10 concurrent requests', async ({ request }) => {
    const concurrentRequests = 10;
    const startTime = Date.now();

    const promises = Array.from({ length: concurrentRequests }, () =>
      request.get('http://localhost:9000/api/status')
    );

    const responses = await Promise.all(promises);
    const totalTime = Date.now() - startTime;
    const avgTime = totalTime / concurrentRequests;

    console.log(`10 concurrent /api/status requests:`);
    console.log(`Total time: ${totalTime}ms`);
    console.log(`Average time: ${avgTime.toFixed(2)}ms`);

    // Most should succeed (some might have issues due to DB checks)
    const successCount = responses.filter(r => r.status() < 500).length;
    console.log(`Success rate: ${(successCount / concurrentRequests * 100).toFixed(1)}%`);

    expect(successCount).toBeGreaterThan(concurrentRequests * 0.8); // 80% success rate
  });
});

test.describe('API Response Times - Sequential Flow Performance', () => {
  test('Complete signup flow end-to-end timing', async ({ request }) => {
    const email = `e2e-perf-${Date.now()}@example.com`;
    const timings: Record<string, number> = {};

    // Step 1: Register
    let start = Date.now();
    const registerResponse = await request.post('http://localhost:9000/api/register', {
      data: {
        email,
        password: 'SecurePassword123!',
        fullName: 'E2E Performance Test',
      },
    });
    timings.register = Date.now() - start;

    await new Promise(resolve => setTimeout(resolve, 500)); // Wait for rate limiter

    // Step 2: Send OTP
    start = Date.now();
    const otpResponse = await request.post('http://localhost:9000/api/send-otp', {
      data: { email, language: 'en' },
    });
    timings.sendOtp = Date.now() - start;

    // Total flow time
    const totalTime = Object.values(timings).reduce((sum, t) => sum + t, 0);

    console.log('Complete signup flow timings:');
    console.log(`  Register: ${timings.register}ms`);
    console.log(`  Send OTP: ${timings.sendOtp}ms`);
    console.log(`  Total: ${totalTime}ms`);

    // Total flow should complete within 2 seconds (excluding waits)
    expect(totalTime).toBeLessThan(2000);
  });
});
