/**
 * SCENARIO: location-update.js
 * Real-time location stress test — simulasi banyak User berjalan serentak.
 *
 * WalkGuide mengirim lokasi setiap 5 detik saat WalkGuide aktif.
 * Ini endpoint paling high-frequency di seluruh sistem.
 *
 * Target: p95 < 300ms, error rate < 1%
 */
import { sleep, check } from "k6";
import {
  DEFAULT_THRESHOLDS,
  handleSummary,
  metricsHelper,
  pickThresholds,
} from "../modules/metrics-helper.js";
import * as api from "../modules/api-client.js";
import { testData } from "../modules/test-data.js";

const BASE_URL = __ENV.BASE_URL || "http://202.46.28.160:8080";

export const options = {
  scenarios: {
    location_stress: {
      executor: "ramping-vus",
      startVUs: 0,
      stages: [
        { duration: "30s", target: 20 }, // ramp-up
        { duration: "90s", target: 50 }, // sustain at 50 walking users
        { duration: "60s", target: 100 }, // peak load
        { duration: "30s", target: 0 }, // ramp-down
      ],
      gracefulRampDown: "15s",
    },
  },
  thresholds: pickThresholds(
    __ENV.BENCH_PROFILE === "local"
      ? {
          http_req_duration: ["p(95)<35000", "p(99)<40000"],
          walkguide_location_latency_ms: ["p(95)<3000", "p(99)<5000"],
        }
      : {
          ...DEFAULT_THRESHOLDS,
          walkguide_location_latency_ms: ["p(95)<300", "p(99)<600"],
          http_req_duration: ["p(95)<400"],
        },
  ),
};

// ── VU shared state (tiap VU punya token sendiri) ─────────────────────────────
let vuTokens = null;
let vuBaseLat = null;
let vuBaseLng = null;

// ── Main VU function ──────────────────────────────────────────────────────────
export default function locationStress() {
  // ── Inisialisasi: register + login sekali per VU ───────────────────────────
  if (!vuTokens) {
    const suffix = `loc_${__VU}_${Date.now()}`;
    const payload = testData.userRegisterPayload(suffix);
    const res = api.register(payload);

    if (res.status === 200) {
      const body = api.parseBody(res);
      if (body && body.data) vuTokens = body.data;
    }

    if (!vuTokens) {
      console.error(`[location] VU ${__VU} failed to get tokens`);
      sleep(2);
      return;
    }

    // Posisi awal acak di Surabaya
    const coord = testData.randomSurabayaCoord(0.05);
    vuBaseLat = coord.lat;
    vuBaseLng = coord.lng;

    // Start walkguide session
    const startRes = api.startWalkguide(vuTokens.accessToken);
    check(startRes, {
      "walkguide-start: 2xx": (r) => r.status >= 200 && r.status < 300,
    });
    sleep(0.5);
  }

  // ── Poll actuator untuk JVM heap (hanya VU 1, tidak mengganggu tes lain) ────
  if (__VU === 1 && __ITER % 10 === 0) {
    metricsHelper.pollJvmHeap(BASE_URL);
    metricsHelper.pollDbConnections(BASE_URL);
  }

  // ── Simulasi walking: kirim 3 location update berturut-turut (15 detik real) ─
  for (let i = 0; i < 3; i++) {
    const locPayload = testData.locationUpdatePayload(vuBaseLat, vuBaseLng);

    const res = api.updateLocation(
      vuTokens.accessToken,
      locPayload.lat,
      locPayload.lng,
      locPayload.accuracy,
      locPayload.speed,
      locPayload.heading,
    );

    check(res, {
      "location-update: status 2xx": (r) => r.status >= 200 && r.status < 300,
      "location-update: latency ok": (r) => r.timings.duration < 500,
    });

    // Update base coordinate (simulasi pergerakan)
    vuBaseLat += testData.randomFloat(-0.0003, 0.0003);
    vuBaseLng += testData.randomFloat(-0.0003, 0.0003);

    // 5 detik interval seperti production
    sleep(5);
  }

  // ── Kadang Guardian juga poll lokasi (setiap 10 iteration) ──────────────────
  // Ini simulasi Guardian membuka map screen
  if (__ITER % 5 === 0 && vuTokens) {
    // Re-login as guardian to test guardian endpoint
    // Dalam real load test, Guardian VU terpisah — di sini kita skip
    // karena token kita adalah ROLE_USER
  }
}

// ── Setup: siapkan backend ────────────────────────────────────────────────────
export function setup() {
  const res = api.ping();
  if (res.status !== 200)
    throw new Error(`Backend not reachable: ${res.status}`);
  console.log(`✅ Location stress test starting. Backend: ${BASE_URL}`);
  return { startTime: Date.now() };
}

// ── Teardown: stop semua walkguide session ────────────────────────────────────
export function teardown(data) {
  console.log(
    `Location stress test finished. Duration: ${(Date.now() - data.startTime) / 1000}s`,
  );
  // Note: individual VU stop walkguide tidak bisa dilakukan di teardown
  // karena token sudah tidak tersedia. Dalam production, session timeout handles ini.
}

export { handleSummary };
