import { signOut } from "next-auth/react";
import { useAuthStore } from "@/store/authStore";
import {
  applyAuthContextHeaders,
  type AuthContextHeaderOptions,
} from "@/lib/requestHeaders";

let isSigningOut = false;

const unwrapPage = async (response: Response) => {
  if (
    !response.headers.get("content-type")?.includes("application/json")
  ) {
    return response;
  }
  const payload = await response.clone().json().catch(() => null);
  if (
    !payload ||
    typeof payload !== "object" ||
    !Array.isArray(payload.items) ||
    typeof payload.total !== "number"
  ) {
    return response;
  }
  const headers = new Headers(response.headers);
  headers.delete("content-length");
  return new Response(JSON.stringify(payload.items), {
    headers,
    status: response.status,
    statusText: response.statusText,
  });
};

const resolveUrl = (input: RequestInfo | URL) => {
  if (typeof input === "string") return input;
  if (input instanceof URL) return input.toString();
  if (input instanceof Request) return input.url;
  return "";
};

export interface ApiFetchInit extends RequestInit, AuthContextHeaderOptions {
  skipAuthRedirect?: boolean;
}

export const apiFetch = async (
  input: RequestInfo | URL,
  init: ApiFetchInit = {},
) => {
  const headers = new Headers(
    init.headers ?? (input instanceof Request ? input.headers : undefined),
  );
  await applyAuthContextHeaders(resolveUrl(input), headers, init);

  const requestInit: RequestInit = {
    ...init,
    headers,
  };
  const response = await fetch(input, requestInit);

  if (response.status === 401 && typeof window !== "undefined" && !init.skipAuthRedirect) {
    useAuthStore.getState().setAccessToken(null);
    if (!isSigningOut) {
      isSigningOut = true;
      await signOut({ redirect: true, callbackUrl: "/login" });
    }
  }

  return unwrapPage(response);
};
