import { useAuthStore } from '@/zustand/authStore';
import axios from 'axios';
import { refreshToken } from './auth/refresh-token';

// Create axios instance
const api = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_URL || 'https://api.example.com',
  headers: { 'Content-Type': 'application/json' },
});

let isRefreshing = false;
let failedQueue: {
  resolve: (value?: unknown) => void;
  reject: (error: unknown) => void;
}[] = [];

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

// Attach access token to requests
api.interceptors.request.use((config) => {
  const state = useAuthStore.getState();
  console.log('AuthStore state:', state);

  const token = state.user?.accessToken;

  if (token) {
    config.headers = config.headers || {};
    config.headers.Authorization = `Bearer ${token}`;
  }
  return config;
});

// Response interceptor to handle 401 and refresh token logic
api.interceptors.response.use(
  (response) => response,
  async (error) => {
    const originalRequest = error.config;

    if (
      error.response?.status === 401 &&
      !originalRequest._retry // custom flag to prevent infinite loops
    ) {
      if (isRefreshing) {
        // Queue the requests while refreshing
        return new Promise((resolve, reject) => {
          failedQueue.push({ resolve, reject });
        })
          .then((token) => {
            originalRequest.headers.Authorization = `Bearer ${token}`;
            return api(originalRequest);
          })
          .catch((err) => {
            return Promise.reject(err);
          });
      }

      originalRequest._retry = true;
      isRefreshing = true;

      const token = useAuthStore.getState().user?.refreshToken;
      console.log(useAuthStore.getState())

      if (!token) {

        useAuthStore.getState().logout();
        return Promise.reject(error);
      }

      try {
        const data = await refreshToken({ token });
        // Update tokens in Zustand store
        useAuthStore.getState().login({
          ...useAuthStore.getState().user!,
          accessToken: data.accessToken,
          refreshToken: data.refreshToken || token,
        });

        api.defaults.headers.common.Authorization = `Bearer ${data.accessToken}`;
        originalRequest.headers.Authorization = `Bearer ${data.accessToken}`;

        processQueue(null, data.accessToken);

        return api(originalRequest);
      } catch (err) {
        processQueue(err, null);
        useAuthStore.getState().logout();
        return Promise.reject(err);
      } finally {
        isRefreshing = false;
      }
    }

    return Promise.reject(error);
  }
);

export { api };
