import axios from 'axios'
import {
  MessageBox,
  Message
} from 'element-ui'
import store from '@/store'

const config = {
  baseURL: process.env.VUE_APP_BASE_API,
  withCredentials: true, // send cookies when cross-domain requests
  timeout: 10000 // request timeout
}

// create an axios instance
const service = axios.create(config)

let baseUrl = process.env.VUE_APP_KEYCLOAK_OPTIONS_URL
if (baseUrl.charAt(0) === '/') {
  baseUrl = `${location.origin}${baseUrl}`
}
const realm = process.env.VUE_APP_KEYCLOAK_OPTIONS_REALM

const keycloakService = axios.create({
  ...config,
  baseURL: `${baseUrl}/admin/realms/${realm}`
})

const tenantService = axios.create(config)

const CancelToken = axios.CancelToken
let source = null
function getCancelToken () {
  if (!source) {
    source = CancelToken.source()
  }
  return source.token
}

export function cancelRequest () {
  if (source) {
    source.cancel('abort')
    source = null
  }
}

// request interceptor
service.interceptors.request.use(
  defaultRequestInterceptor,
  debug
)
keycloakService.interceptors.request.use(
  defaultRequestInterceptor,
  debug
)
tenantService.interceptors.request.use(
  defaultRequestInterceptor,
  debug
)
tenantService.interceptors.request.use(
  config => {
    const { tenant, org, user } = config.params || config.data || {}
    console.log('url', config.method, config.url)
    console.log('tenant', tenant)
    console.log('org', org)
    console.log('user', user)
    if (!tenant && !org && !user) {
      Message({
        type: 'warning',
        message: '缺失scope信息'
      })
      return Promise.reject()
    }
    return config
  },
  null
)

// response interceptor
service.interceptors.response.use(
  responseInterceptor,
  responseErrorInterceptor
)
keycloakService.interceptors.response.use(
  response => response.data,
  responseErrorInterceptor
)
tenantService.interceptors.response.use(
  responseInterceptor,
  responseErrorInterceptor
)

export default service

export const keycloakRequest = keycloakService

export const tenantRequest = tenantService

function defaultRequestInterceptor (config) {
  // do something before request is sent
  if (!store.getters.token) {
    return Promise.reject()
  }
  config.headers['Authorization'] = `Bearer ${store.getters.token}`
  if (!config.background) {
    config.cancelToken = getCancelToken()
  }
  return config
}

function debug (error) {
  console.log('http debug', error) // for debug
  return Promise.reject(error)
}

function responseInterceptor (response) {
  const res = response.data || {}

  if (res.success) {
    return res
  }

  if (!response.config?.custom) {
    Message({
      type: 'error',
      message: res.errMessage || '请求异常'
    })
  }

  return Promise.reject(res)
}

function responseErrorInterceptor (error) {
  if (!error) {
    return Promise.reject({ isCancel: true })
  }
  const isCancel = axios.isCancel(error)
  const { response, config } = error
  if (response) {
    const { status } = response
    if (status === 401) {
      store.dispatch('user/clearToekn')
      // to re-login
      MessageBox.confirm(
        '登录状态已过期，请重新登录',
        '系统提示',
        {
          confirmButtonText: '重新登录',
          center: true,
          showClose: false,
          showCancelButton: false,
          closeOnClickModal: false
        }
      ).then(() => {
        store.dispatch('user/logout')
      })
    } else if (status === 403) {
      Message({
        type: 'warning',
        message: '暂无相关权限，请联系管理员'
      })
    } else if (!config?.custom) {
      const { errMessage, errorMessage } = response.data
      Message({
        type: 'error',
        message: errMessage || errorMessage || '请求异常'
      })
    }
    return Promise.reject({ isCancel, ...response.data })
  }

  let { message } = error
  if (!config?.custom && !isCancel) {
    if (message) {
      if (/timeout/.test(message)) {
        message = '请求超时'
      }
    } else {
      message = '请求异常'
    }
    Message({
      type: 'error',
      message
    })
  }
  return Promise.reject({ isCancel, errCode: -1, errMessage: message })
}
