/**
 * Extracts the error message from a fetch response
 */
export async function getRespErrorText(resp: Response): Promise<string> {
  const respText = await resp.text();

  if (!respText.trim()) {
    return "An unexpected error occurred";
  }

  let respJson: unknown;
  try {
    respJson = JSON.parse(respText);
  } catch {
    return respText.trim();
  }

  if (typeof respJson === "object" && respJson !== null && "detail" in respJson) {
    return String((respJson as { detail: unknown }).detail);
  }

  // fallback to original text if JSON object not in expected format
  return respText.trim();
}

/**
 * All-in-one wrapper around `fetch` that returns JSON data or an error message
 */
export async function fetchApi(...args: Parameters<typeof fetch>) {
  try {
    const response = await fetch(...args);

    if (!response.ok) {
      const errorText = await getRespErrorText(response);
      return { ok: false as const, data: null, error: errorText };
    }

    const data: unknown = await response.json();
    return { ok: true as const, data, error: null };
  } catch (error) {
    if (error instanceof Error) {
      return { ok: false as const, data: null, error: error.message };
    }

    return { ok: false as const, data: null, error: "An unexpected error occurred" };
  }
}
