/**
 * WalkGuide API Client — Reusable HTTP wrapper for k6 tests
 * Semua request ke Spring Boot backend melewati modul ini.
 */
import http from "k6/http";
import { check, fail } from "k6";
import { metricsHelper } from "./metrics-helper.js";

const BASE_URL = __ENV.BASE_URL || "http://202.46.28.160:8080";
const API_BASE = `${BASE_URL}/api/v1`;

/**
 * Default headers tanpa auth
 */
function jsonHeaders(extra = {}) {
  return Object.assign(
    { "Content-Type": "application/json", Accept: "application/json" },
    extra,
  );
}

/**
 * Default headers dengan Bearer token
 */
function authHeaders(token, extra = {}) {
  return jsonHeaders(
    Object.assign({ Authorization: `Bearer ${token}` }, extra),
  );
}

// ──────────────────────────────────────────────
// AUTH endpoints
// ──────────────────────────────────────────────

export function register(payload) {
  const res = http.post(`${API_BASE}/auth/register`, JSON.stringify(payload), {
    headers: jsonHeaders(),
    tags: { endpoint: "register" },
  });
  metricsHelper.recordEndpoint("register", res);
  return res;
}

export function login(email, password) {
  const res = http.post(
    `${API_BASE}/auth/login`,
    JSON.stringify({ email, password }),
    { headers: jsonHeaders(), tags: { endpoint: "login" } },
  );
  metricsHelper.recordEndpoint("login", res);
  return res;
}

export function refreshToken(refreshTok) {
  const res = http.post(
    `${API_BASE}/auth/refresh`,
    JSON.stringify({ refreshToken: refreshTok }),
    { headers: jsonHeaders(), tags: { endpoint: "refresh_token" } },
  );
  metricsHelper.recordEndpoint("refresh_token", res);
  return res;
}

export function logout(token) {
  const res = http.post(`${API_BASE}/auth/logout`, null, {
    headers: authHeaders(token),
    tags: { endpoint: "logout" },
  });
  metricsHelper.recordEndpoint("logout", res);
  return res;
}

export function ping() {
  const res = http.get(`${API_BASE}/auth/ping`, { tags: { endpoint: "ping" } });
  metricsHelper.recordEndpoint("ping", res);
  return res;
}

export function updateFcmToken(token, fcmToken) {
  const res = http.put(
    `${API_BASE}/auth/fcm-token`,
    JSON.stringify({ fcmToken }),
    { headers: authHeaders(token), tags: { endpoint: "fcm_token" } },
  );
  metricsHelper.recordEndpoint("fcm_token", res);
  return res;
}

// ──────────────────────────────────────────────
// PAIRING endpoints
// ──────────────────────────────────────────────

export function inviteUser(token, uniqueUserId) {
  const res = http.post(
    `${API_BASE}/pairing/invite`,
    JSON.stringify({ uniqueUserId }),
    { headers: authHeaders(token), tags: { endpoint: "pairing_invite" } },
  );
  metricsHelper.recordEndpoint("pairing_invite", res);
  return res;
}

export function respondPairing(token, pairingId, accept) {
  const res = http.post(
    `${API_BASE}/pairing/respond`,
    JSON.stringify({ pairingId, accept }),
    { headers: authHeaders(token), tags: { endpoint: "pairing_respond" } },
  );
  metricsHelper.recordEndpoint("pairing_respond", res);
  return res;
}

export function getPairingStatus(token) {
  const res = http.get(`${API_BASE}/pairing/status`, {
    headers: authHeaders(token),
    tags: { endpoint: "pairing_status" },
  });
  metricsHelper.recordEndpoint("pairing_status", res);
  return res;
}

export function unpair(token) {
  const res = http.del(`${API_BASE}/pairing/unpair`, null, {
    headers: authHeaders(token),
    tags: { endpoint: "pairing_unpair" },
  });
  metricsHelper.recordEndpoint("pairing_unpair", res);
  return res;
}

// ──────────────────────────────────────────────
// USER endpoints
// ──────────────────────────────────────────────

export function getUserProfile(token) {
  const res = http.get(`${API_BASE}/user/profile`, {
    headers: authHeaders(token),
    tags: { endpoint: "user_profile" },
  });
  metricsHelper.recordEndpoint("user_profile", res);
  return res;
}

export function updateLocation(
  token,
  lat,
  lng,
  accuracy = 5.0,
  speed = 1.4,
  heading = 90.0,
) {
  const res = http.post(
    `${API_BASE}/user/location`,
    JSON.stringify({ lat, lng, accuracy, speed, heading }),
    { headers: authHeaders(token), tags: { endpoint: "location_update" } },
  );
  metricsHelper.recordEndpoint("location_update", res);
  return res;
}

export function logObstacle(token, payload) {
  const res = http.post(`${API_BASE}/user/obstacle`, JSON.stringify(payload), {
    headers: authHeaders(token),
    tags: { endpoint: "obstacle_log" },
  });
  metricsHelper.recordEndpoint("obstacle_log", res);
  return res;
}

export function triggerSos(token, triggerType, lat, lng) {
  const res = http.post(
    `${API_BASE}/user/sos`,
    JSON.stringify({ triggerType, lat, lng }),
    { headers: authHeaders(token), tags: { endpoint: "sos_trigger" } },
  );
  metricsHelper.recordEndpoint("sos_trigger", res);
  return res;
}

export function getActivityLogs(token, page = 0, size = 20) {
  const res = http.get(
    `${API_BASE}/user/activity-logs?page=${page}&size=${size}`,
    { headers: authHeaders(token), tags: { endpoint: "activity_logs" } },
  );
  metricsHelper.recordEndpoint("activity_logs", res);
  return res;
}

export function getNotifications(token, page = 0, size = 20) {
  const res = http.get(
    `${API_BASE}/user/notifications?page=${page}&size=${size}`,
    { headers: authHeaders(token), tags: { endpoint: "notifications" } },
  );
  metricsHelper.recordEndpoint("notifications", res);
  return res;
}

export function getUnreadCount(token) {
  const res = http.get(`${API_BASE}/user/notifications/unread-count`, {
    headers: authHeaders(token),
    tags: { endpoint: "unread_count" },
  });
  metricsHelper.recordEndpoint("unread_count", res);
  return res;
}

export function markAllRead(token) {
  const res = http.put(`${API_BASE}/user/notifications/mark-all-read`, null, {
    headers: authHeaders(token),
    tags: { endpoint: "mark_all_read" },
  });
  metricsHelper.recordEndpoint("mark_all_read", res);
  return res;
}

export function markOneRead(token, notifId) {
  const res = http.put(`${API_BASE}/user/notifications/${notifId}/read`, null, {
    headers: authHeaders(token),
    tags: { endpoint: "mark_one_read" },
  });
  metricsHelper.recordEndpoint("mark_one_read", res);
  return res;
}

export function startWalkguide(token) {
  const res = http.post(`${API_BASE}/user/walkguide/start`, null, {
    headers: authHeaders(token),
    tags: { endpoint: "walkguide_start" },
  });
  metricsHelper.recordEndpoint("walkguide_start", res);
  return res;
}

export function stopWalkguide(token) {
  const res = http.post(`${API_BASE}/user/walkguide/stop`, null, {
    headers: authHeaders(token),
    tags: { endpoint: "walkguide_stop" },
  });
  metricsHelper.recordEndpoint("walkguide_stop", res);
  return res;
}

export function getUserSettings(token) {
  const res = http.get(`${API_BASE}/user/settings`, {
    headers: authHeaders(token),
    tags: { endpoint: "user_settings_get" },
  });
  metricsHelper.recordEndpoint("user_settings_get", res);
  return res;
}

export function updateUserSettings(token, payload) {
  const res = http.put(`${API_BASE}/user/settings`, JSON.stringify(payload), {
    headers: authHeaders(token),
    tags: { endpoint: "user_settings_put" },
  });
  metricsHelper.recordEndpoint("user_settings_put", res);
  return res;
}

export function getUserAiConfig(token) {
  const res = http.get(`${API_BASE}/user/ai-config`, {
    headers: authHeaders(token),
    tags: { endpoint: "ai_config_get" },
  });
  metricsHelper.recordEndpoint("ai_config_get", res);
  return res;
}

// ──────────────────────────────────────────────
// GUARDIAN endpoints
// ──────────────────────────────────────────────

export function getGuardianDashboard(token) {
  const res = http.get(`${API_BASE}/guardian/dashboard`, {
    headers: authHeaders(token),
    tags: { endpoint: "guardian_dashboard" },
  });
  metricsHelper.recordEndpoint("guardian_dashboard", res);
  return res;
}

export function getUserLocation(token) {
  const res = http.get(`${API_BASE}/guardian/user-location`, {
    headers: authHeaders(token),
    tags: { endpoint: "guardian_user_location" },
  });
  metricsHelper.recordEndpoint("guardian_user_location", res);
  return res;
}

export function getLocationHistory(token, page = 0, size = 50) {
  const res = http.get(
    `${API_BASE}/guardian/location-history?page=${page}&size=${size}`,
    { headers: authHeaders(token), tags: { endpoint: "location_history" } },
  );
  metricsHelper.recordEndpoint("location_history", res);
  return res;
}

export function getObstacleLogs(token, page = 0, size = 20) {
  const res = http.get(
    `${API_BASE}/guardian/obstacle-logs?page=${page}&size=${size}`,
    { headers: authHeaders(token), tags: { endpoint: "obstacle_logs_get" } },
  );
  metricsHelper.recordEndpoint("obstacle_logs_get", res);
  return res;
}

export function sendNotification(token, payload) {
  const res = http.post(
    `${API_BASE}/guardian/notifications/send`,
    JSON.stringify(payload),
    { headers: authHeaders(token), tags: { endpoint: "send_notification" } },
  );
  metricsHelper.recordEndpoint("send_notification", res);
  return res;
}

export function getSosEvents(token, page = 0, size = 20) {
  const res = http.get(
    `${API_BASE}/guardian/sos-events?page=${page}&size=${size}`,
    { headers: authHeaders(token), tags: { endpoint: "sos_events_get" } },
  );
  metricsHelper.recordEndpoint("sos_events_get", res);
  return res;
}

export function acknowledgeSos(token, sosId) {
  const res = http.put(`${API_BASE}/guardian/sos/${sosId}/acknowledge`, null, {
    headers: authHeaders(token),
    tags: { endpoint: "sos_acknowledge" },
  });
  metricsHelper.recordEndpoint("sos_acknowledge", res);
  return res;
}

export function getAiConfig(token) {
  const res = http.get(`${API_BASE}/guardian/ai-config`, {
    headers: authHeaders(token),
    tags: { endpoint: "ai_config_guardian_get" },
  });
  metricsHelper.recordEndpoint("ai_config_guardian_get", res);
  return res;
}

export function updateAiConfig(token, payload) {
  const res = http.put(
    `${API_BASE}/guardian/ai-config`,
    JSON.stringify(payload),
    {
      headers: authHeaders(token),
      tags: { endpoint: "ai_config_guardian_put" },
    },
  );
  metricsHelper.recordEndpoint("ai_config_guardian_put", res);
  return res;
}

export function getActivityLogsGuardian(token, page = 0, size = 20) {
  const res = http.get(
    `${API_BASE}/guardian/activity-logs?page=${page}&size=${size}`,
    {
      headers: authHeaders(token),
      tags: { endpoint: "activity_logs_guardian" },
    },
  );
  metricsHelper.recordEndpoint("activity_logs_guardian", res);
  return res;
}

export function getGeofenceConfig(token) {
  const res = http.get(`${API_BASE}/guardian/geofence`, {
    headers: authHeaders(token),
    tags: { endpoint: "geofence_get" },
  });
  metricsHelper.recordEndpoint("geofence_get", res);
  return res;
}

export function updateGeofenceConfig(token, payload) {
  const res = http.put(
    `${API_BASE}/guardian/geofence`,
    JSON.stringify(payload),
    { headers: authHeaders(token), tags: { endpoint: "geofence_put" } },
  );
  metricsHelper.recordEndpoint("geofence_put", res);
  return res;
}

// ──────────────────────────────────────────────
// SHARED check helpers
// ──────────────────────────────────────────────

export function checkSuccess(res, label) {
  check(res, {
    [`${label}: status 2xx`]: (r) => r.status >= 200 && r.status < 300,
    [`${label}: has body`]: (r) => r.body && r.body.length > 0,
  });
}

export function parseBody(res) {
  try {
    return JSON.parse(res.body);
  } catch (_) {
    return null;
  }
}
