import { AxiosResponse, AxiosError } from "axios";
import Cookies from "js-cookie";
import { toast } from "react-toastify";
import { API_ENDPOINTS, api } from "../lib/api";
import { COOKIE_KEYS } from "../lib/shared/cookies";

let isRefreshing = false;
let failedQueue: any[] = [];

const processQueue = (error: any, token: string | null = null) => {
  failedQueue.forEach((prom) => {
    if (error) {
      prom.reject(error);
    } else {
      prom.resolve(token);
    }
  });

  failedQueue = [];
};

export const responseInterceptor = (response: AxiosResponse) => {
  return response;
};

export const responseErrorHandler = async (error: AxiosError) => {
  const originalRequest = error.config as any;

  if (error.response?.status === 401 && !originalRequest._retry) {
    if (isRefreshing) {
      return new Promise<string>((resolve, reject) => {
        failedQueue.push({ resolve, reject });
      })
        .then((token: string) => {
          originalRequest.headers["Authorization"] = "Bearer " + token;
          return api(originalRequest);
        })
        .catch((err) => {
          return Promise.reject(err);
        });
    }

    originalRequest._retry = true;
    isRefreshing = true;

    try {
      const refreshToken = Cookies.get(COOKIE_KEYS.refresh_token);
      if (!refreshToken) {
        throw new Error("Refresh token not found.");
      }

      const response = await api.post(API_ENDPOINTS.USER.REFRESH_TOKEN, {
        refresh_token: refreshToken,
      });

      const { access_token, refresh_token } = response.data.data as {
        access_token: string;
        refresh_token: string;
      };

      if (!access_token || !refresh_token) {
        throw new Error("Invalid token received from refresh endpoint.");
      }

      Cookies.set(COOKIE_KEYS.access_token, access_token);
      Cookies.set(COOKIE_KEYS.refresh_token, refresh_token);

      if (originalRequest.headers) {
        originalRequest.headers.Authorization = `Bearer ${access_token}`;
      }
      processQueue(null, access_token);
      return api(originalRequest);
    } catch (refreshError) {
      processQueue(refreshError, null);
      Cookies.remove(COOKIE_KEYS.access_token);
      Cookies.remove(COOKIE_KEYS.refresh_token);
      Cookies.remove(COOKIE_KEYS.user);

      if (typeof window !== "undefined") {
        localStorage.removeItem("auth-token");
        localStorage.removeItem("user-data");
        window.location.href = "/login";
      }

      const errorMessage =
        (
          (refreshError as AxiosError).response?.data as {
            message: string;
            error: { code: string; message: string };
          }
        )?.error?.message || (refreshError as Error).message;
      toast.error(errorMessage);

      return Promise.reject(refreshError);
    } finally {
      isRefreshing = false;
    }
  }

  const errorMessage =
    (
      error.response?.data as {
        message: string;
        error: { code: string; message: string };
      }
    )?.error?.message || error.message;
  toast.error(errorMessage);
  return Promise.reject(error);
};
