import axios from 'axios'
import { toast } from 'vue3-toastify'
import { tokenService } from '@/services/api/token-service'
import { camelize, snakize } from '@/utils/convert-to-camel-snake'

const defaultHeaders = {
  'Content-Type': 'application/json',
  Accept: 'application/json',
}

const addAuthTokenInterceptor = (instance) => {
  instance.interceptors.request.use(
    (config) => {
      const token = tokenService.getToken()
      const headers = {
        ...config.headers,
        Authorization: token ? `Bearer ${token}` : '',
      }
      if (config.data instanceof FormData) {
        delete headers['Content-Type']
      }
      return { ...config, headers }
    },
    null,
    { synchronous: true }
  )
}

const addSnakizeInterceptor = (instance) => {
  instance.interceptors.request.use(
    (config) => {
      if (config.data instanceof FormData || config.noSnakize) {
        return config
      }
      return {
        ...config,
        params: config.params ? snakize(config.params) : {},
        data: config.data ? snakize(config.data) : undefined,
      }
    },
    (e) => Promise.reject(e)
  )
}

const addResponseUnwrapInterceptor = (instance) => {
  instance.interceptors.response.use(
    (res) => {
      if (typeof res?.data === 'number' || typeof res?.data === 'boolean') {
        return { data: res.data }
      }
      return res?.data || res
    },
    (e) => Promise.reject(e)
  )
}

const addCamelizeInterceptor = (instance) => {
  instance.interceptors.response.use(
    (res) => camelize(res),
    (e) => Promise.reject(e)
  )
}

const _addUnauthorizeInterceptor = (instance) => {
  instance.interceptors.response.use(
    (res) => res,
    async (e) => {
      if (e?.response?.status === 401) {
        tokenService.clearAll()
        toast('نشست شما تایید نشد، لطفا مجدد وارد شوید')
        try {
          const { default: router } = await import('@/router')
          router.push('/login').catch(() => {})
        } catch {}
      }
      throw e
    }
  )
}

const createInstance = (baseUrl, { headers = {}, ...configs } = {}) => {
  const instance = axios.create({
    timeout: 15_000,
    baseURL: baseUrl,
    headers: { ...defaultHeaders, ...headers },
    ...configs,
  })
  addAuthTokenInterceptor(instance)
  addResponseUnwrapInterceptor(instance)
  addCamelizeInterceptor(instance)
  addSnakizeInterceptor(instance)
  // _addUnauthorizeInterceptor(instance)
  return instance
}

export const http = createInstance(import.meta.env.VITE_API_BASE_URL || '')

export { createInstance }
