// HISTORICAL — multi-flow k6 script kept for reference only.
// The canonical load test is wrk against /api/leaderboard/{competitionId}
// (see load-test/run-wrk.sh and the README's "Load Testing" section).

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

// All config lives in load-test/.env — run via: .\load-test\run.ps1
//
// BASE_URL        default http://localhost:5000
// COMPETITION_ID  competition to test against
// MATCH_IDS       comma-separated match IDs open for betting
// GROUP_IDS       comma-separated group IDs (group flow skipped if omitted)
// TEST_USERS      comma-separated username:password pairs
//                 e.g. alice:pass1,bob:pass2,charlie:pass3

const BASE      = __ENV.BASE_URL || 'http://localhost:5000';
const COMP      = __ENV.COMPETITION_ID;
const MATCH_IDS = (__ENV.MATCH_IDS || '').split(',').map(s => s.trim()).filter(Boolean).map(Number);
const GROUP_IDS = (__ENV.GROUP_IDS || '').split(',').map(s => s.trim()).filter(Boolean).map(Number);

// Runs once before any VU starts. Logs in every test user and returns their
// token+fgp pairs so no credentials are ever passed as env vars at runtime.
export function setup() {
  const users = (__ENV.TEST_USERS || '').split(',').map(s => s.trim()).filter(Boolean);
  if (!users.length) throw new Error('TEST_USERS must contain at least one username:password entry');

  return users.map(entry => {
    const sep      = entry.indexOf(':');
    const username = entry.slice(0, sep);
    const password = entry.slice(sep + 1);

    const res = http.post(
      `${BASE}/api/user/login`,
      JSON.stringify({ username, password }),
      { headers: { 'Content-Type': 'application/json' } }
    );

    if (res.status !== 200) {
      throw new Error(`Login failed for "${username}": HTTP ${res.status} — ${res.body}`);
    }

    const body      = JSON.parse(res.body);
    const cookieArr = res.cookies['Fgp'] || res.cookies['__Host-Fgp'] || [];
    const fgp       = cookieArr.length ? cookieArr[0].value : null;

    if (!fgp) throw new Error(`No FGP cookie in login response for "${username}"`);

    return { token: body.token, fgp };
  });
}

// Three scenarios running concurrently, weighted by VU allocation:
//   browse  (50 VUs) — read-only:   competitions → matches → leaderboard
//   bettor  (35 VUs) — read+write:  bets list → place bet → check stats
//   group   (15 VUs) — read-only:   groups list → group leaderboard

export const options = {
  scenarios: {
    browse: {
      executor: 'ramping-vus',
      exec: 'browseFlow',
      startVUs: 0,
      stages: [
        { duration: '30s', target: 10 },
        { duration: '1m',  target: 50 },
        { duration: '30s', target: 50 },
        { duration: '30s', target: 0  },
      ],
      gracefulRampDown: '30s',
    },
    bettor: {
      executor: 'ramping-vus',
      exec: 'bettorFlow',
      startVUs: 0,
      stages: [
        { duration: '30s', target: 7  },
        { duration: '1m',  target: 35 },
        { duration: '30s', target: 35 },
        { duration: '30s', target: 0  },
      ],
      gracefulRampDown: '30s',
    },
    group: {
      executor: 'ramping-vus',
      exec: 'groupFlow',
      startVUs: 0,
      stages: [
        { duration: '30s', target: 3  },
        { duration: '1m',  target: 15 },
        { duration: '30s', target: 15 },
        { duration: '30s', target: 0  },
      ],
      gracefulRampDown: '30s',
    },
  },
  thresholds: {
    'http_req_failed':                ['rate<0.01'],
    'http_req_duration':              ['p(95)<500'],
    'http_req_duration{flow:browse}': ['p(95)<300'],
    'http_req_duration{flow:bettor}': ['p(95)<600'],
    'http_req_duration{flow:group}':  ['p(95)<400'],
  },
};

function pick(arr) {
  return arr[Math.floor(Math.random() * arr.length)];
}

function randInt(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

function randSleep(min, max) {
  sleep(Math.random() * (max - min) + min);
}

function headers(auth) {
  const user = pick(auth);
  return {
    'Authorization': `Bearer ${user.token}`,
    'Cookie': `__Host-Fgp=${user.fgp}`,
    'Content-Type': 'application/json',
  };
}

export function browseFlow(auth) {
  const h    = headers(auth);
  const tags = { flow: 'browse' };

  const compsRes = http.get(`${BASE}/api/competition`, { headers: h, tags });
  check(compsRes, { 'competitions 200': r => r.status === 200 });
  randSleep(0.5, 1.5);

  const matchesRes = http.get(`${BASE}/api/match?competitionId=${COMP}`, { headers: h, tags });
  check(matchesRes, {
    'matches 200':      r => r.status === 200,
    'matches is array': r => { try { return Array.isArray(JSON.parse(r.body)); } catch { return false; } },
  });
  randSleep(1, 2);

  const lbRes = http.get(`${BASE}/api/leaderboard/${COMP}`, { headers: h, tags });
  check(lbRes, {
    'leaderboard 200':         r => r.status === 200,
    'leaderboard has entries': r => { try { const b = JSON.parse(r.body); return Array.isArray(b.entries); } catch { return false; } },
  });
  randSleep(1, 3);
}

export function bettorFlow(auth) {
  if (!MATCH_IDS.length) return;

  const h    = headers(auth);
  const tags = { flow: 'bettor' };

  const betsRes = http.get(`${BASE}/api/bet?competitionId=${COMP}`, { headers: h, tags });
  check(betsRes, { 'bets list 200': r => r.status === 200 });
  randSleep(1, 2);

  const matchId = pick(MATCH_IDS);
  const body    = JSON.stringify({ homeScore: randInt(0, 4), awayScore: randInt(0, 4) });
  const putRes  = http.put(`${BASE}/api/bet/${matchId}`, body, { headers: h, tags });
  check(putRes, { 'bet upsert 2xx': r => r.status >= 200 && r.status < 300 });
  randSleep(0.5, 1.5);

  const statsRes = http.get(`${BASE}/api/bet/match/${matchId}/stats`, { headers: h, tags });
  check(statsRes, { 'bet stats 200': r => r.status === 200 });
  randSleep(1, 2);
}

export function groupFlow(auth) {
  if (!GROUP_IDS.length) return;

  const h    = headers(auth);
  const tags = { flow: 'group' };

  const groupsRes = http.get(`${BASE}/api/group?competitionId=${COMP}`, { headers: h, tags });
  check(groupsRes, { 'groups 200': r => r.status === 200 });
  randSleep(0.5, 1.5);

  const groupId = pick(GROUP_IDS);
  const lbRes   = http.get(`${BASE}/api/group/${groupId}/leaderboard`, { headers: h, tags });
  check(lbRes, { 'group leaderboard 200': r => r.status === 200 });
  randSleep(1, 3);
}

export default function () {}
