import { store } from "../index";
import { setLogout } from "@/state";
const g = globalThis;

if (!g.__refreshPromise) {
  g.__refreshPromise = null;
}

async function refreshAccessToken() {
  const refreshRes = await fetch(`${import.meta.env.VITE_BASE_URL}/auth/refresh`, {
    method: "POST",
    credentials: "include",
  });

  if (!refreshRes.ok) {
    store.dispatch(setLogout());
    window.location.href = "/";
    throw new Error("Refresh failed");
  }

  const data = await refreshRes.json();

  const state = store.getState();

  if (!user) {
    store.dispatch(setLogout());
    return { authError: true };
  }
  store.dispatch(setUser({ user: state.user, token: data.token }));

  //   store.dispatch(
  //     setUser({
  //       user: state.user,
  //       token: data.token,
  //     }),
  //   );

  return data.token;
}

export async function apiFetch(url, options = {}) {
  const makeRequest = async (token) => {
    return fetch(url, {
      ...options,
      headers: {
        ...options.headers,
        Authorization: token ? `Bearer ${token}` : "",
      },
      credentials: "include",
    });
  };

  try {
    // current token
    let token = store.getState().token;

    // first attempt
    let res = await makeRequest(token);

    // only refresh on 401
    if (res.status !== 401) {
      return res;
    }

    console.log("Access token expired, refreshing...");

    // create ONE shared refresh promise
    if (!g.__refreshPromise) {
      g.__refreshPromise = refreshAccessToken()
        .catch((err) => {
          console.error("Refresh error:", err);
          throw err;
        })
        .finally(() => {
          g.__refreshPromise = null;
        });
    }

    // all requests await same promise
    const newAccessToken = await g.__refreshPromise;

    // retry once with new token
    res = await makeRequest(newAccessToken);

    // still unauthorized after refresh
    if (res.status === 401) {
      store.dispatch(setLogout());
      window.location.href = "/";
      return { authError: true };
    }

    return res;
  } catch (err) {
    console.error("apiFetch error:", err);
    return { authError: true };
  }
}
