import Axios, { InternalAxiosRequestConfig } from 'axios'
import Cookies from 'js-cookie'
import { toast } from 'react-toastify'
import { NetworkStore } from '../components/ErrorBoundary/GlobalNetworkLoadingIndicator'

const isDevelopment = process.env.NODE_ENV == 'development'

const tenantCode =
  isDevelopment || window.location.hostname === 'localhost'
    ? Cookies.get('campx_tenant')
    : window.location.hostname.split('.')[0]
const institutionCode = window.location.pathname.split('/')[1]

export const formatParams = (params) => {
  return Object.fromEntries(
    Object.entries(params ?? {})?.map((i) => [
      i[0],
      i[1] === '__empty__' ? '' : i[1],
    ]),
  )
}

let axios = Axios.create({
  baseURL: process.env.REACT_APP_API_HOST,
  withCredentials: true,
  headers: {
    'x-tenant-id': tenantCode,
    'x-institution-code': institutionCode,
  },
})

axios.interceptors.request.use(
  function (config: InternalAxiosRequestConfig) {
    const params = formatParams(config?.params)
    NetworkStore.update((s) => {
      s.loading = true
    })
    const sessionKey = Cookies.get('campx_session_key')
    const openPaymentsKey = Cookies.get('campx_open_payments_key')

    if (isDevelopment && sessionKey) {
      config.headers.set('campx_session_key', sessionKey)
    }

    if (openPaymentsKey) {
      config.headers.set('campx_open_payments_key', openPaymentsKey)
    }

    return {
      ...config,
      params,
    }
  },
  function (error) {
    NetworkStore.update((s) => {
      s.loading = false
    })
    return Promise.reject(error)
  },
)

axios.interceptors.response.use(
  function (response) {
    NetworkStore.update((s) => {
      s.loading = false
    })
    return response
  },
  function (err) {
    NetworkStore.update((s) => {
      s.loading = false
    })

    // Check if the error is an unauthorized error (401)
    if (err?.response && err?.response?.status === 401) {
      Cookies.remove('campx_session_key')
      Cookies.remove('campx_tenant')
      Cookies.remove('campx_institution')
    }

    return Promise.reject(err)
  },
)

export default axios

export const axiosErrorToast = (error: any, fallback?: string) => {
  const fallbackMessage = fallback ?? 'Something went wrong.'
  const errorMessage =
    typeof error?.response?.data?.message !== 'string'
      ? error?.response?.data?.message?.join('\n') ?? fallbackMessage
      : error?.response?.data?.message

  return toast.error(errorMessage)
}
