import { getApiBase } from "../api-base.js";
import { platformRuntime } from "../platform/runtime.js";

export const API_BASE = getApiBase(import.meta.env?.VITE_API_URL, { isNative: platformRuntime.isNative });
const authenticationRequiredListeners = new Set();

export async function request(path, options = {}) {
  let response;
  let body;
  try {
    const method = options.method ?? "GET";
    const mutation = ["POST", "PUT", "PATCH", "DELETE"].includes(method);
    response = await (options.fetchImpl ?? globalThis.fetch)(`${API_BASE}${path}`, {
      method,
      credentials: "include",
      signal: options.signal,
      headers: {
        ...(options.body !== undefined ? { "content-type": "application/json" } : {}),
        ...(mutation ? { "x-code-remote-csrf": "1" } : {}),
        ...(options.headers ?? {})
      },
      body: options.body !== undefined ? JSON.stringify(options.body) : undefined
    });
    body = await response.json();
  } catch (error) {
    if (options.signal?.aborted || error?.name === "AbortError") {
      const aborted = new Error("request_aborted");
      aborted.name = "AbortError";
      throw aborted;
    }
    throw new Error("pc_unreachable");
  }

  if (!response.ok) {
    const code = body.error ?? "request_failed";
    if (response.status === 401 && code === "authentication_required") {
      for (const listener of authenticationRequiredListeners) listener();
    }
    throw new Error(code);
  }
  return body;
}

export function subscribeAuthenticationRequired(listener) {
  authenticationRequiredListeners.add(listener);
  return () => authenticationRequiredListeners.delete(listener);
}
