/**
 * SCENARIO: notification-send.js
 * Mass notification broadcast — Guardian kirim pesan ke User.
 *
 * Simulasi banyak Guardian mengirim notifikasi serentak + User membaca.
 * Termasuk test mark-read dan unread-count endpoints.
 *
 * Target: p95 < 500ms, error rate < 1%
 */
import { sleep, check } from "k6";
import {
  DEFAULT_THRESHOLDS,
  handleSummary,
} from "../modules/metrics-helper.js";
import * as api from "../modules/api-client.js";
import { testData } from "../modules/test-data.js";

export const options = {
  scenarios: {
    // Scenario A: Guardian send notifications
    guardian_send: {
      executor: "constant-vus",
      vus: 25,
      duration: "120s",
      exec: "guardianSend",
      tags: { scenario: "guardian_send" },
    },
    // Scenario B: User read notifications (mulai setelah 10s)
    user_read: {
      executor: "constant-vus",
      vus: 25,
      duration: "100s",
      startTime: "10s",
      exec: "userRead",
      tags: { scenario: "user_read" },
    },
  },
  thresholds: {
    ...DEFAULT_THRESHOLDS,
    walkguide_notif_latency_ms: ["p(95)<500", "p(99)<1000"],
  },
};

// ── Shared VU states ──────────────────────────────────────────────────────────
let guardianVuToken = null;
let userVuToken = null;

// ── EXEC: Guardian send notifications ────────────────────────────────────────
export function guardianSend() {
  if (!guardianVuToken) {
    const suffix = `notif_g_${__VU}_${Date.now()}`;
    const res = api.register(testData.guardianRegisterPayload(suffix));
    if (res.status === 200) {
      const b = api.parseBody(res);
      if (b && b.data) guardianVuToken = b.data.accessToken;
    }
    if (!guardianVuToken) {
      sleep(2);
      return;
    }
    sleep(0.3);
  }

  // Kirim 1-3 notifikasi per iterasi
  const count = testData.randomInt(1, 3);
  for (let i = 0; i < count; i++) {
    const payload = testData.sendNotificationPayload();
    const res = api.sendNotification(guardianVuToken, payload);

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

    sleep(0.2);
  }

  // Cek activity log guardian
  if (__ITER % 5 === 0) {
    const logsRes = api.getActivityLogsGuardian(guardianVuToken);
    check(logsRes, {
      "guardian-logs: 2xx": (r) => r.status >= 200 && r.status < 300,
    });
  }

  sleep(testData.randomFloat(0.5, 1.5, 1));
}

// ── EXEC: User read notifications ─────────────────────────────────────────────
export function userRead() {
  if (!userVuToken) {
    const suffix = `notif_u_${__VU}_${Date.now()}`;
    const res = api.register(testData.userRegisterPayload(suffix));
    if (res.status === 200) {
      const b = api.parseBody(res);
      if (b && b.data) userVuToken = b.data.accessToken;
    }
    if (!userVuToken) {
      sleep(2);
      return;
    }
    sleep(0.3);
  }

  // ── Step 1: Cek unread count ─────────────────────────────────────────────
  const unreadRes = api.getUnreadCount(userVuToken);
  check(unreadRes, {
    "unread-count: 2xx": (r) => r.status >= 200 && r.status < 300,
    "unread-count: has data": (r) => {
      const b = api.parseBody(r);
      return b && b.data !== undefined;
    },
  });

  sleep(0.2);

  // ── Step 2: Get notification list ────────────────────────────────────────
  const page = __ITER % 3; // test pagination
  const notifRes = api.getNotifications(userVuToken, page, 20);
  check(notifRes, {
    "get-notifs: 2xx": (r) => r.status >= 200 && r.status < 300,
    "get-notifs: has list": (r) => {
      const b = api.parseBody(r);
      return b && b.data !== undefined;
    },
  });

  // Extract first notif id untuk test mark-read
  let firstNotifId = null;
  if (notifRes.status >= 200 && notifRes.status < 300) {
    const body = api.parseBody(notifRes);
    if (
      body &&
      body.data &&
      Array.isArray(body.data.content) &&
      body.data.content.length > 0
    ) {
      firstNotifId = body.data.content[0].id;
    }
  }

  sleep(0.2);

  // ── Step 3: Mark individual notification read (jika ada) ─────────────────
  if (firstNotifId) {
    const markRes = api.markOneRead(userVuToken, firstNotifId);
    check(markRes, {
      "mark-one-read: 2xx": (r) => r.status >= 200 && r.status < 300,
    });
    sleep(0.2);
  }

  // ── Step 4: Mark all read (setiap 5 iterasi) ─────────────────────────────
  if (__ITER % 5 === 0) {
    const markAllRes = api.markAllRead(userVuToken);
    check(markAllRes, {
      "mark-all-read: 2xx": (r) => r.status >= 200 && r.status < 300,
    });
  }

  sleep(testData.randomFloat(0.5, 2.0, 1));
}

export function setup() {
  const res = api.ping();
  if (res.status !== 200)
    throw new Error(`Backend not reachable: ${res.status}`);
  console.log(
    "📬 Notification send/read test starting (2 parallel scenarios).",
  );
}

export { handleSummary };
