import axios from 'axios'
import { message, Modal, notification } from 'antd'
import { history } from '../utils/history'
import { DebugPortalDebugPortalGetBasicSessionResp } from './api'
import { createGlobalState } from 'react-hooks-global-state'

const state = createGlobalState({
  session: null as DebugPortalDebugPortalGetBasicSessionResp | null
})

export function prettyAxiosError(error: any): string {
  if (axios.isAxiosError(error)) {
    if (error.response?.data?.message) {
      return error.response.data.message
    } else {
      return error.message
    }
  } else {
    return '' + error
  }
}

export function setSession(
  session: DebugPortalDebugPortalGetBasicSessionResp | null
) {
  state.setGlobalState('session', () => session)
}

export function useSession() {
  return state.useGlobalState('session')
}

const client = axios.create({
  timeout: 10 * 1000
})

client.interceptors.request.use((config) => {
  if (
    config.method !== 'options' &&
    state.getGlobalState('session')?.csrf_token
  ) {
    if (!config.headers) {
      config.headers = {}
    }
    config.headers['x-csrf-token'] = state.getGlobalState('session')?.csrf_token
  }
  return config
})

client.interceptors.response.use(undefined, (error) => {
  if (!axios.isAxiosError(error)) {
    return Promise.reject(error)
  }
  {
    const customizedConfig: any = error.response?.config
    if (customizedConfig?.noPostprocess) {
      return Promise.reject(error)
    }
  }

  // 401 not authenticated, got to login
  const status = error.response?.status
  if (status === 401) {
    message.error('Not authenticated, redirecting to sign in page...')
    history.push('/login')
    return Promise.reject(error)
  }

  const method = error.config.method ?? ''
  if (method === 'get') {
    notification.error({
      message: 'Request failed',
      description: prettyAxiosError(error)
    })
  } else if (['post', 'put', 'delete', 'patch'].includes(method)) {
    Modal.error({
      title: 'Request failed',
      content: prettyAxiosError(error)
    })
  }
  return Promise.reject(error)
})

export default client
