"use server";

import { getValidAccessToken } from "ikoncomponents";
import { redirect } from "next/navigation";

export interface ExtraOptionsProps {
  isAccessTokenRequird?: boolean;
  revalidatePaths?: string[];
  isReturnErrorResult?: boolean;
}

export const baseApiRequest = async (
  url: string,
  init: RequestInit,
  extraOptions?: ExtraOptionsProps,
) => {
  const headers = new Headers(init.headers);

  if (!headers.get("Content-Type")) {
    headers.set("Content-Type", "application/json");
  }

  if (extraOptions?.isAccessTokenRequird !== false) {
    const accessToken = await getValidAccessToken(
      process.env.NEXT_PUBLIC_IKON_API_URL || "",
    );

    if (!accessToken?.trim()) {
      redirect("/login.html");
    }

    headers.set("Authorization", `Bearer ${accessToken.trim()}`);
  }

  const response = await fetch(url, {
    ...init,
    headers,
  });

  const contentType = response.headers.get("Content-Type");

  if (!response.ok) {
    let body = "";
    try {
      body = contentType?.includes("application/json")
        ? await response.json()
        : await response.text();
    } catch {
      /* ignore */
    }
    const message =
      typeof body === "string"
        ? body
        : (() => {
            try {
              return JSON.stringify(body);
            } catch {
              return String(body);
            }
          })();
    console.error(
      `API Request Failed - ${init.method} ${url}: HTTP ${response.status} ${message}`,
    );
    if (extraOptions?.isReturnErrorResult) {
      return body;
    }
    throw new Error(`HTTP ${response.status}: ${message}`);
  }

  return contentType?.includes("application/json")
    ? await response.json()
    : await response.text();
};
