import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';
import { BASE_URL, SLA_THRESHOLDS, uniquePhone } from '../lib/config.js';

const loginDuration = new Trend('login_duration', true);
const registerDuration = new Trend('register_duration', true);
const loginFailRate = new Rate('login_failures');

export const options = {
  scenarios: {
    auth_load: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '30s', target: 50 },   // ramp up
        { duration: '1m', target: 100 },    // sustain 100 concurrent
        { duration: '30s', target: 0 },     // ramp down
      ],
      gracefulRampDown: '10s',
    },
  },
  thresholds: {
    ...SLA_THRESHOLDS,
    login_duration: ['p(95)<500'],
    register_duration: ['p(95)<800'],
    login_failures: ['rate<0.05'],
  },
};

export function setup() {
  // Pre-register a pool of users for login tests
  const users = [];
  for (let i = 0; i < 50; i++) {
    const phone = `0910${String(i).padStart(6, '0')}`;
    const payload = JSON.stringify({
      phone,
      password: 'LoadTest@1234!',
      fullName: `K6 Auth User ${i}`,
      email: `k6-auth-${i}@goodgo.test`,
    });

    const res = http.post(`${BASE_URL}/auth/register`, payload, {
      headers: { 'Content-Type': 'application/json' },
      tags: { name: 'setup_register' },
    });

    if (res.status === 200 || res.status === 201 || res.status === 409) {
      users.push({ phone, password: 'LoadTest@1234!' });
    }
  }
  return { users };
}

export default function (data) {
  const vu = __VU;
  const iter = __ITER;

  // Alternate between register and login
  if (iter % 3 === 0) {
    // Register new user
    const phone = uniquePhone();
    const payload = JSON.stringify({
      phone,
      password: 'LoadTest@1234!',
      fullName: `K6 New User ${phone}`,
      email: `k6-new-${phone}@goodgo.test`,
    });

    const res = http.post(`${BASE_URL}/auth/register`, payload, {
      headers: { 'Content-Type': 'application/json' },
      tags: { name: 'POST /auth/register' },
    });

    registerDuration.add(res.timings.duration);
    check(res, {
      'register: status 200|201': (r) => r.status === 200 || r.status === 201,
      'register: has accessToken': (r) => {
        try { return JSON.parse(r.body).accessToken !== undefined; } catch { return false; }
      },
    });
  } else {
    // Login existing user
    const user = data.users[vu % data.users.length];
    if (!user) return;

    const res = http.post(
      `${BASE_URL}/auth/login`,
      JSON.stringify({ phone: user.phone, password: user.password }),
      {
        headers: { 'Content-Type': 'application/json' },
        tags: { name: 'POST /auth/login' },
      },
    );

    loginDuration.add(res.timings.duration);
    const ok = check(res, {
      'login: status 200|201': (r) => r.status === 200 || r.status === 201,
      'login: has accessToken': (r) => {
        try { return JSON.parse(r.body).accessToken !== undefined; } catch { return false; }
      },
    });
    loginFailRate.add(!ok);

    // Optionally hit profile with the token
    if (res.status === 200 || res.status === 201) {
      try {
        const tokens = JSON.parse(res.body);
        const profileRes = http.get(`${BASE_URL}/auth/profile`, {
          headers: { Authorization: `Bearer ${tokens.accessToken}` },
          tags: { name: 'GET /auth/profile' },
        });
        check(profileRes, {
          'profile: status 200': (r) => r.status === 200,
        });
      } catch (_) { /* ignore parse errors */ }
    }
  }

  sleep(Math.random() * 2 + 0.5);
}
