/* =====================================================================
 * Client de l'API serveur (session par cookie HttpOnly).
 * ===================================================================== */

class ApiError extends Error {
  constructor(status, message, code) {
    super(message);
    this.status = status;
    this.code = code;
  }
}

let unauthorizedHandler = null;

function setUnauthorizedHandler(fn) {
  unauthorizedHandler = fn;
}

async function apiRequest(path, { method = 'GET', body } = {}) {
  const headers = { 'X-Requested-With': 'SAPManager' };
  if (body !== undefined) headers['Content-Type'] = 'application/json';
  let res;
  try {
    res = await fetch(`/api/${path}`, {
      method,
      headers,
      credentials: 'same-origin',
      cache: 'no-store',
      body: body === undefined ? undefined : JSON.stringify(body),
    });
  } catch (err) {
    throw new ApiError(0, 'Serveur injoignable : vérifiez la connexion.', 'network');
  }
  let payload = null;
  try {
    payload = await res.json();
  } catch (err) {
    payload = null;
  }
  if (!res.ok) {
    const error = new ApiError(res.status, (payload && payload.error) || `Erreur serveur (${res.status})`, payload && payload.code);
    if (res.status === 401 && path !== 'login' && unauthorizedHandler) unauthorizedHandler();
    throw error;
  }
  return payload;
}

/** Erreur temporaire (réseau, serveur indisponible) : l'envoi peut être retenté. */
const isRetryableError = (err) => !(err instanceof ApiError) || err.status === 0 || err.status >= 500 || err.status === 429;
