import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend, Counter } from 'k6/metrics';
{{#each dynamic_imports}}
{{{this}}}
{{/each}}

{{#each dynamic_globals}}
{{{this}}}
{{/each}}

// Custom metrics per operation
{{#each operations}}
const {{this.name}}_latency = new Trend('{{this.metric_name}}_latency');
const {{this.name}}_errors = new Rate('{{this.metric_name}}_errors');
{{/each}}

// Test configuration
export const options = {
  {{#if skip_tls_verify}}
  insecureSkipTLSVerify: true,
  {{/if}}
  scenarios: {
    {{scenario_name}}: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        {{#each stages}}
        { duration: '{{this.duration}}', target: {{this.target}} },
        {{/each}}
      ],
      gracefulRampDown: '10s',
    },
  },
  thresholds: {
    'http_req_duration': ['{{threshold_percentile}}<{{threshold_ms}}'],
    'http_req_failed': ['rate<{{max_error_rate}}'],
  },
};

const BASE_URL = '{{base_url}}';

export default function () {
  {{#each operations}}
  // Operation {{@index}}: {{this.display_name}}
  {
    const headers = {{{this.headers}}};

    {{#if this.has_body}}
    {{#if this.body_is_dynamic}}
    // Dynamic body with runtime placeholders
    const payload = {{{this.body}}};
    {{else}}
    const payload = {{{this.body}}};
    {{/if}}
    {{#if this.path_is_dynamic}}
    const url = {{{this.path}}};
    const res = http.{{this.method}}(`${BASE_URL}${url}`, JSON.stringify(payload), { headers });
    {{else}}
    const res = http.{{this.method}}(`${BASE_URL}{{{this.path}}}`, JSON.stringify(payload), { headers });
    {{/if}}
    {{else if this.is_get_or_head}}
    // GET and HEAD only take 2 args: http.get(url, params)
    {{#if this.path_is_dynamic}}
    const url = {{{this.path}}};
    const res = http.{{this.method}}(`${BASE_URL}${url}`, { headers });
    {{else}}
    const res = http.{{this.method}}(`${BASE_URL}{{{this.path}}}`, { headers });
    {{/if}}
    {{else}}
    // POST, PUT, PATCH, DELETE take 3 args: http.post(url, body, params)
    {{#if this.path_is_dynamic}}
    const url = {{{this.path}}};
    const res = http.{{this.method}}(`${BASE_URL}${url}`, null, { headers });
    {{else}}
    const res = http.{{this.method}}(`${BASE_URL}{{{this.path}}}`, null, { headers });
    {{/if}}
    {{/if}}

    const success = check(res, {
      '{{this.display_name}}: status is OK': (r) => r.status >= 200 && r.status < 300,
      '{{this.display_name}}: has response': (r) => r.body !== null && r.body.length > 0,
    });

    {{this.name}}_latency.add(res.timings.duration);
    {{this.name}}_errors.add(!success);

    sleep(1);
  }
  {{/each}}
}

export function handleSummary(data) {
  return {
    'stdout': textSummary(data, { indent: ' ', enableColors: true }),
  };
}

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

  const metrics = data.metrics;
  let output = '\n';

  output += indent + '='.repeat(60) + '\n';
  output += indent + 'Load Test Summary\n';
  output += indent + '='.repeat(60) + '\n\n';

  // Request metrics
  if (metrics.http_reqs && metrics.http_reqs.values) {
    const count = metrics.http_reqs.values.count || 0;
    const rate = metrics.http_reqs.values.rate;
    output += indent + `Total Requests: ${count}\n`;
    output += indent + `Request Rate: ${rate != null ? rate.toFixed(2) : '0.00'} req/s\n\n`;
  } else {
    output += indent + 'Total Requests: 0\n';
    output += indent + 'Request Rate: 0.00 req/s\n\n';
  }

  // Duration metrics
  if (metrics.http_req_duration && metrics.http_req_duration.values) {
    const v = metrics.http_req_duration.values;
    output += indent + 'Response Times:\n';
    output += indent + `  Min: ${v.min != null ? v.min.toFixed(2) : 'N/A'}ms\n`;
    output += indent + `  Avg: ${v.avg != null ? v.avg.toFixed(2) : 'N/A'}ms\n`;
    output += indent + `  Med: ${v.med != null ? v.med.toFixed(2) : 'N/A'}ms\n`;
    output += indent + `  p90: ${v['p(90)'] != null ? v['p(90)'].toFixed(2) : 'N/A'}ms\n`;
    output += indent + `  p95: ${v['p(95)'] != null ? v['p(95)'].toFixed(2) : 'N/A'}ms\n`;
    output += indent + `  p99: ${v['p(99)'] != null ? v['p(99)'].toFixed(2) : 'N/A'}ms\n`;
    output += indent + `  Max: ${v.max != null ? v.max.toFixed(2) : 'N/A'}ms\n\n`;
  } else {
    output += indent + 'Response Times: No successful requests\n\n';
  }

  // Error rate
  if (metrics.http_req_failed && metrics.http_req_failed.values) {
    const rate = metrics.http_req_failed.values.rate;
    const errorRate = rate != null ? (rate * 100).toFixed(2) : '100.00';
    output += indent + `Error Rate: ${errorRate}%\n\n`;
  } else {
    output += indent + 'Error Rate: N/A\n\n';
  }

  output += indent + '='.repeat(60) + '\n';

  return output;
}
