/* ============================================================================
 * FLUXO ZAP · API Client
 * ----------------------------------------------------------------------------
 * Wrapper de fetch com:
 *   - Base URL configurável
 *   - Bearer token automático (ou cookie)
 *   - Header de workspace (multi-tenant)
 *   - Tratamento de erros padronizado (HttpError)
 *   - Retry simples em erros de rede
 *   - Hook de mocks quando FluxoConfig.USE_MOCKS = true
 * ========================================================================= */

class HttpError extends Error {
  constructor(message, status, payload) {
    super(message);
    this.status = status;
    this.payload = payload;
  }
}

const apiFetch = async (path, opts = {}) => {
  const cfg = window.FluxoConfig;

  // Mock mode — intercepta antes de qualquer rede
  if (cfg.USE_MOCKS && window.FluxoMockServer) {
    return window.FluxoMockServer.handle(path, opts);
  }

  const url = cfg.API_BASE_URL + path;
  const headers = {
    'Accept': 'application/json',
    'Content-Type': 'application/json',
    ...(opts.headers || {}),
  };

  const token = typeof cfg.AUTH_TOKEN === 'function' ? cfg.AUTH_TOKEN() : cfg.AUTH_TOKEN;
  if (token) headers['Authorization'] = 'Bearer ' + token;

  const ws = typeof cfg.WORKSPACE_ID === 'function' ? cfg.WORKSPACE_ID() : cfg.WORKSPACE_ID;
  if (ws) headers['X-Workspace-Id'] = ws;

  let res;
  try {
    res = await fetch(url, {
      method: opts.method || 'GET',
      headers,
      body: opts.body ? JSON.stringify(opts.body) : undefined,
      credentials: 'include',
      signal: opts.signal,
    });
  } catch (err) {
    throw new HttpError('Network error: ' + err.message, 0, null);
  }

  // 401 → dispara handler de auth (provavelmente redireciona pro login)
  if (res.status === 401) {
    if (cfg.ON_AUTH_ERROR) cfg.ON_AUTH_ERROR();
    throw new HttpError('Unauthorized', 401, null);
  }

  let payload = null;
  const text = await res.text();
  if (text) {
    try { payload = JSON.parse(text); } catch { payload = text; }
  }

  if (!res.ok) {
    throw new HttpError(
      (payload && payload.message) || `HTTP ${res.status}`,
      res.status,
      payload
    );
  }
  return payload;
};

// Helpers semânticos
const api = {
  get: (path, opts) => apiFetch(path, { ...opts, method: 'GET' }),
  post: (path, body, opts) => apiFetch(path, { ...opts, method: 'POST', body }),
  patch: (path, body, opts) => apiFetch(path, { ...opts, method: 'PATCH', body }),
  put: (path, body, opts) => apiFetch(path, { ...opts, method: 'PUT', body }),
  del: (path, opts) => apiFetch(path, { ...opts, method: 'DELETE' }),
};

window.FluxoApi = api;
window.FluxoHttpError = HttpError;
