/**
 * K6 Load Test - Rate Search Endpoint
 *
 * Target: 100 requests/second
 * Duration: 5 minutes
 *
 * Run: k6 run rate-search.test.js
 */

import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';

// Custom metrics
const errorRate = new Rate('errors');
const searchDuration = new Trend('search_duration');

// Test configuration
export const options = {
  stages: [
    { duration: '1m', target: 20 }, // Ramp up to 20 users
    { duration: '2m', target: 50 }, // Ramp up to 50 users
    { duration: '1m', target: 100 }, // Ramp up to 100 users
    { duration: '3m', target: 100 }, // Stay at 100 users
    { duration: '1m', target: 0 }, // Ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<2000'], // 95% of requests must complete below 2s
    http_req_failed: ['rate<0.01'], // Error rate must be less than 1%
    errors: ['rate<0.05'], // Business error rate must be less than 5%
  },
};

// Base URL
const BASE_URL = __ENV.API_URL || 'http://localhost:4000/api/v1';

// Auth token (should be set via environment variable)
const AUTH_TOKEN = __ENV.AUTH_TOKEN || '';

// Test data - common trade lanes
const tradeLanes = [
  {
    origin: 'NLRTM', // Rotterdam
    destination: 'CNSHA', // Shanghai
    containerType: '40HC',
  },
  {
    origin: 'USNYC', // New York
    destination: 'GBLON', // London
    containerType: '20ST',
  },
  {
    origin: 'SGSIN', // Singapore
    destination: 'USOAK', // Oakland
    containerType: '40ST',
  },
  {
    origin: 'DEHAM', // Hamburg
    destination: 'BRRIO', // Rio de Janeiro
    containerType: '40HC',
  },
  {
    origin: 'AEDXB', // Dubai
    destination: 'INMUN', // Mumbai
    containerType: '20ST',
  },
];

export default function () {
  // Select random trade lane
  const tradeLane = tradeLanes[Math.floor(Math.random() * tradeLanes.length)];

  // Prepare request payload
  const payload = JSON.stringify({
    origin: tradeLane.origin,
    destination: tradeLane.destination,
    departureDate: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], // 2 weeks from now
    containers: [
      {
        type: tradeLane.containerType,
        quantity: 1,
      },
    ],
  });

  const params = {
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${AUTH_TOKEN}`,
    },
    tags: { name: 'RateSearch' },
  };

  // Make request
  const startTime = Date.now();
  const response = http.post(`${BASE_URL}/rates/search`, payload, params);
  const duration = Date.now() - startTime;

  // Record metrics
  searchDuration.add(duration);

  // Check response
  const success = check(response, {
    'status is 200': r => r.status === 200,
    'response has quotes': r => {
      try {
        const body = JSON.parse(r.body);
        return body.quotes && body.quotes.length > 0;
      } catch (e) {
        return false;
      }
    },
    'response time < 2s': r => duration < 2000,
  });

  errorRate.add(!success);

  // Small delay between requests
  sleep(1);
}

export function handleSummary(data) {
  return {
    stdout: textSummary(data, { indent: ' ', enableColors: true }),
    'load-test-results/rate-search-summary.json': JSON.stringify(data),
  };
}

function textSummary(data, options) {
  const indent = options.indent || '';
  const enableColors = options.enableColors || false;

  return `
${indent}Test Summary - Rate Search Load Test
${indent}=====================================
${indent}
${indent}Total Requests: ${data.metrics.http_reqs.values.count}
${indent}Failed Requests: ${data.metrics.http_req_failed.values.rate * 100}%
${indent}
${indent}Response Times:
${indent}  Average: ${data.metrics.http_req_duration.values.avg.toFixed(2)}ms
${indent}  Median:  ${data.metrics.http_req_duration.values.med.toFixed(2)}ms
${indent}  95th:    ${data.metrics.http_req_duration.values['p(95)'].toFixed(2)}ms
${indent}  99th:    ${data.metrics.http_req_duration.values['p(99)'].toFixed(2)}ms
${indent}
${indent}Requests/sec: ${data.metrics.http_reqs.values.rate.toFixed(2)}
${indent}
${indent}Business Metrics:
${indent}  Error Rate: ${(data.metrics.errors.values.rate * 100).toFixed(2)}%
${indent}  Avg Search Duration: ${data.metrics.search_duration.values.avg.toFixed(2)}ms
  `;
}
