// Inspired by https://github.com/orval-labs/orval/blob/master/samples/next-app-with-fetch/custom-fetch.ts

import { logout } from "../auth";
import { SESSION_EXPIRED_KEY } from "../config/constants";
import { APIError } from "./api-error";
import { getHeaders, getRequestUrl, isJson } from "./utils";

export interface fetchAPIOptions {
  logoutOn401?: boolean;
}

export const fetchAPI= async <T>(
  pathname: string,
  { params, logoutOn401, ...requestInit }: RequestInit & fetchAPIOptions & { params?: Record<string, string> } = {},
): Promise<T> => {
  const requestUrl = getRequestUrl(pathname, params);
  const isMultipartFormData = requestInit.body instanceof FormData;

  const response = await fetch(requestUrl, {
    ...requestInit,
    credentials: "include",
    headers: getHeaders(requestInit.headers, isMultipartFormData),
  });

  if ((logoutOn401 ?? true) && response.status === 401) {
    sessionStorage.setItem(SESSION_EXPIRED_KEY, 'true');
    logout();
  }

  if (response.ok) {
    const data = response.status === 204 ? null : await response.json();
    return { status: response.status, data, headers: response.headers } as T;
  }

  const data = await response.text();
  if (isJson(data)) {
    throw new APIError(response.status, JSON.parse(data));
  }
  throw new APIError(response.status);
};
