import getLocaleCS from '@/shared/lib/getLocaleCS';
import {
  getRefToken,
  getToken,
  removeRefToken,
  removeToken,
  setRefToken,
  setToken,
} from '@/shared/lib/token';
import axios, { AxiosError } from 'axios';
import { getLocale } from 'next-intl/server';
import { LanguageRoutes } from '../i18n/types';
import { BASE_URL } from './URLs';

const httpClient = axios.create({
  baseURL: BASE_URL,
  timeout: 10000,
});

httpClient.interceptors.request.use(
  async (config) => {
    // Language configs
    let language = LanguageRoutes.UZ;
    try {
      language = (await getLocale()) as LanguageRoutes;
    } catch {
      language = getLocaleCS() || LanguageRoutes.UZ;
    }

    config.headers['Accept-Language'] = language;
    const accessToken = getToken();
    if (accessToken) {
      config.headers['Authorization'] = `Bearer ${accessToken}`;
    }

    return config;
  },
  (error) => Promise.reject(error),
);

httpClient.interceptors.response.use(
  async (response) => response,
  async (error) => {
    console.error('API error:', error);
    if ((error as AxiosError)?.status === 403) {
      try {
        const refToken = getRefToken();
        if (!refToken) {
          removeToken();
          removeRefToken();
        }
        const { data } = await axios.post(
          `${BASE_URL}api/v1/accounts/refresh/token/`,
          { refresh: refToken },
        );
        setToken(data.access);
        setRefToken(data.refresh);
      } catch {
        removeToken();
        removeRefToken();
      }
    } else if ((error as AxiosError)?.status === 401) {
      try {
        const refToken = getRefToken();
        if (!refToken) {
          removeToken();
          removeRefToken();
        }
        const { data } = await axios.post(
          `${BASE_URL}api/v1/accounts/refresh/token/`,
          { refresh: refToken },
        );
        setToken(data.access);
        setRefToken(data.refresh);
      } catch {
        removeToken();
        removeRefToken();
        window.location.href = '/';
      }
    }
    return Promise.reject(error);
  },
);

export default httpClient;
