import { getWooStoreApiUrl } from "@/lib/config";

export interface StorefrontSession {
  cartToken?: string;
  nonce?: string;
}

export interface WooMoney {
  currency_code: string;
  currency_minor_unit: number;
}

export function formatWooMoney(value: string | undefined, money: WooMoney) {
  const minorUnit = money.currency_minor_unit ?? 2;
  const rawNumber = Number(value ?? "0");
  const amount = rawNumber / 10 ** minorUnit;

  return new Intl.NumberFormat("hr-HR", {
    style: "currency",
    currency: money.currency_code || "EUR",
    minimumFractionDigits: minorUnit,
    maximumFractionDigits: minorUnit,
  }).format(amount);
}

export function mergeStorefrontSession(
  response: Response,
  session: StorefrontSession,
): StorefrontSession {
  return {
    cartToken: response.headers.get("cart-token") ?? session.cartToken,
    nonce: response.headers.get("nonce") ?? session.nonce,
  };
}

export async function fetchWooStoreJson<T>(
  pathname: string,
  {
    method = "GET",
    session,
    body,
    retryOnAuthFailure = true,
    refreshPath = "/cart",
  }: {
    method?: "GET" | "POST" | "PUT";
    session: StorefrontSession;
    body?: Record<string, unknown>;
    retryOnAuthFailure?: boolean;
    refreshPath?: string;
  },
) {
  const response = await fetch(getWooStoreApiUrl(pathname), {
    method,
    headers: {
      Accept: "application/json",
      ...(body ? { "Content-Type": "application/json" } : {}),
      ...(session.cartToken ? { "Cart-Token": session.cartToken } : {}),
      ...(session.nonce ? { Nonce: session.nonce } : {}),
    },
    ...(body ? { body: JSON.stringify(body) } : {}),
    cache: "no-store",
  });

  if ((response.status === 401 || response.status === 403) && retryOnAuthFailure) {
    const refreshed = await fetchWooStoreJson<unknown>(refreshPath, {
      method: "GET",
      session,
      retryOnAuthFailure: false,
      refreshPath,
    });

    return fetchWooStoreJson<T>(pathname, {
      method,
      session: refreshed.session,
      body,
      retryOnAuthFailure: false,
      refreshPath,
    });
  }

  if (!response.ok) {
    let message = `Woo Store request failed: ${response.status} ${pathname}`;

    try {
      const payload = (await response.json()) as { message?: string; code?: string };
      message = payload.message || payload.code || message;
    } catch {}

    throw new Error(message);
  }

  return {
    payload: (await response.json()) as T,
    session: mergeStorefrontSession(response, session),
  };
}

