import Axios, { AxiosRequestConfig } from 'axios'
import Cookies from 'js-cookie'
import { toast } from 'react-toastify'
import { NetworkStore } from '../components/ErrorBoundary/GlobalNetworkLoadingIndicator'
import { isDevelopment, isSetup } from '../constants'
import { InstitutionsStore } from '../shared-state/InstitutionsStore'

const sessionKey = Cookies.get('campx_session_key')
const clientId = window.location.pathname.split('/')[1] ?? 'campx_dev'
const institutionId = window.location.pathname.split('/')[2] ?? 'campx_dev'
const openPaymentsKey = Cookies.get('campx_open_payments_key')

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': clientId,
    ...((isDevelopment || isSetup) && sessionKey
      ? { campx_session_key: sessionKey }
      : {}),

    ...(openPaymentsKey && {
      campx_open_payments_key: openPaymentsKey,
    }),
  },
})

axios.interceptors.request.use(
  function (config: AxiosRequestConfig) {
    const { current } = InstitutionsStore.getRawState()
    if (current) {
      config.headers['x-institution-code'] = current.code
    } else {
      config.headers['x-institution-code'] = institutionId
    }

    const params = formatParams(config?.params)
    NetworkStore.update((s) => {
      s.loading = true
    })
    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
    })
    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)
}
