import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'

export const HttpClientFactory = (data: {
  config?: AxiosRequestConfig
  getSocketId?: () => string
  authenticate?: () => Promise<unknown>
}): AxiosInstance => {
  const instance = axios.create(data.config)

  instance.interceptors.request.use(
    function(config) {
      config.headers['X-Site'] = process.env.PROJECT_NAME

      if (data.getSocketId) {
        config.headers['X-Socket-Id'] = data.getSocketId()
      }

      return config
    },
    function(error) {
      return Promise.reject(error)
    }
  )

  instance.interceptors.response.use(
    r => r,
    async error => {
      if (data.authenticate) {
        if (error.response.status !== 401 || error.config.retry) {
          throw error
        }

        await data.authenticate()

        const retryRequest = {
          ...error.config,
          retry: true,
        }

        return instance(retryRequest)
      } else {
        throw error
      }
    }
  )

  return instance
}
