import {
  BaseQueryApi,
  createApi,
  FetchArgs,
  fetchBaseQuery,
  FetchBaseQueryError,
} from "@reduxjs/toolkit/query/react";
import { RootState } from "../store";
import { logOut, setCredentials } from "../features/auth/authSlice";

const baseURL = import.meta.env.VITE_API_BASE_URL as string;

const baseQuery = fetchBaseQuery({
  baseUrl: baseURL,
  // credentials: 'include',
  prepareHeaders: (headers) => {
    const user = window.localStorage.getItem("authUser");
    const token = user && JSON.parse(user || "");

    if (token) {
      headers.set("authorization", `Bearer ${token?.jwtToken}`);
    }
    return headers;
  },
});

const baseQueryWithReauth = async (
  args: string | FetchArgs,
  api: BaseQueryApi,
  extraOptions: object
) => {
  let result: { data: unknown } | { error: FetchBaseQueryError } =
    await baseQuery(args, api, extraOptions);

  if ("error" in result) {
    if (result.error.status === 401 || result.error.status === 403) {
      console.log("sending refresh token");
      // send refresh token to get new access token
      const refreshResult = await baseQuery("/refresh", api, extraOptions);
      console.log(refreshResult);
      if (refreshResult?.data) {
        const user = (api.getState() as RootState).auth;
        // store the new token
        api.dispatch(setCredentials({ ...user, ...refreshResult.data }));
        // retry the original query with new access token
        result = await baseQuery(args, api, extraOptions);
      } else {
        api.dispatch(logOut());
      }
    }
  }

  return result;
};

export const apiSlice = createApi({
  baseQuery: baseQueryWithReauth,
  tagTypes: ["Enum"],
  endpoints: () => ({}),
});
