import axios from 'axios'
import { Loading, Message } from 'element-ui'
import store from '@/store'
import { getToken, getExpiresDate } from '@/utils/auth'
import { saveAs } from 'file-saver'
import { blobValidate } from '@/utils'
import i18n from '@/locale'
import router from '@/router'
import moment from 'moment'
import browserIO from '@/utils/browserIO'
const envs = [
  { 'env': 'development_local', 'url': '/ags-api-dev/' },
  { 'env': 'dev_local', 'url': '/ags-api-dev/' }
]
const env = envs.find(x => x.env === process.env.NODE_ENV)
const whiteList = ['/web/auth/captcha', '/dev-api/api/refresh/']
// create an axios instance
const service = axios.create({
  // ags-api 會透過代理去調用接口
  baseURL: env === undefined ? process.env.VUE_APP_BASE_API : env.url,
  withCredentials: true, // send cookies when cross-domain requests
  timeout: 30000 // request timeout
})
let downloadLoadingInstance

// request interceptor
service.interceptors.request.use(
  async config => {
    // 是否已過期, 過期重新獲取Token
    const isExpiresDate = moment().isAfter(moment(getExpiresDate()))
    if (isExpiresDate && config.url !== '/web/auth/refresh_token') {
      await store.dispatch('account/refreshToken')
    }
    if (getToken()) {
      config.headers['Authorization'] = 'Bearer ' + getToken()
    }
    return config
  },
  error => {
    console.log('service.interceptors.request:', error) // for debug
    return Promise.reject(error)
  }
)

// response interceptor
service.interceptors.response.use(
  async response => {
    const res = response.data
    // 判斷是否為檔案類型
    if (response.config.responseType === 'blob') return res

    // 白名單直接回傳資料
    if (whiteList.includes(response.config.url)) return res

    switch (res.code) {
      case '1': // code = 1 為運營看板暫時使用
        return res
      case 40301:
      case 40309: // Token失效
        if (router.currentRoute.name !== 'login') {
          Message({
            message: res.message || res.msg || 'Error',
            type: 'error',
            duration: 5 * 1000
          })
          await store.dispatch('account/logout')
          router.push({ path: '/login' })
        }
        return Promise.reject(res)
      case 40307: // Token已過期, 開始重新獲取Token流程
        return refreshToken(response)
      case 20000: // 正常狀態
        return res
    }

    // obtain專用
    const { status, data } = response
    if (status === 200 && !data.code) {
      return data
    }

    Message({
      message: res.message || res.msg || 'Error',
      type: 'error',
      duration: 5 * 1000
    })
    // return Promise.reject(res)
    return res
  },
  error => {
    if (error.response) {
      switch (error.response.status) {
        case 400: {
          Message({
            message: `${error.response.status}:${error.message}`,
            type: 'error',
            duration: 5 * 1000
          })
          break
        }
        case 401: {
          Message({
            message: `${error.response.status}:${i18n.t('request.relogin')}`,
            type: 'error',
            duration: 5 * 1000
          })
          break
        }
        case 404:
          Message({
            message: `${error.response.status}: ${i18n.t('request.notfound')}`,
            type: 'error',
            duration: 5 * 1000
          })
          break
        case 403:
          Message({
            message: `${error.response.data.code}: ${error.response.data.message}`,
            type: 'error',
            duration: 5 * 1000
          })
          break
        case 500:
          Message({
            message: `${error.response.status}: ${i18n.t('request.systemError')}`,
            type: 'error',
            duration: 5 * 1000
          })
          break

        default:
          Message({
            message: `${error.response.status}: ${i18n.t('request.systemMaintenance')}。`,
            type: 'error',
            duration: 5 * 1000
          })
      }
      console.log('agsRequest Error: ' + error) // for debug
      return Promise.reject(error)
    } else {
      console.log('agsRequest other Error : ' + error) // for debug
      if (error.message) {
        Message({
          message: error.message,
          type: 'error',
          duration: 5 * 1000
        })
      }
      return Promise.reject(error)
    }
  }
)

const refreshToken = (response) => {
  // 從登入來的就顯示帳號密碼錯誤
  if (response.config.url === '/ags/web/auth/login') {
    const accountAndPasswordError = { message: i18n.t('login.accountAndPasswordError') }
    Message({
      message: accountAndPasswordError.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(accountAndPasswordError.message)
  }

  // 如果是從refreshToke就離開, 表示refreshToken也失效
  if (response.config.url.indexOf('/web/auth/refresh_token') > 0) {
    return Promise.reject(response)
  }

  // 原始 request 資訊
  const originalRequest = response.config
  // 依據 refresh_token 刷新 access_token 並重發 request
  return store.dispatch('account/refreshToken').then(response => {
    // 刷新Token並重新登入應用
    browserIO.login()
    return service(originalRequest)
  }).catch(async error => {
    Message({
      message: `${i18n.t('request.relogin')}`,
      type: 'error',
      duration: 5 * 1000
    })
    await store.dispatch('account/logout')
    router.push({ path: '/login' })
    return Promise.reject(error)
  })
}

// 通用下載方法
export function download(url, params, filename, type = 'POST') {
  downloadLoadingInstance = Loading.service({ text: '正在下载数据，请稍候', spinner: 'el-icon-loading' })
  return service.get(url, params, {
    responseType: 'blob'
  }).then(async(data) => {
    const isValidate = await blobValidate(data)
    if (isValidate) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      Message.error('下载的档案内容不正确')
    }
    downloadLoadingInstance.close()
  }).catch((r) => {
    console.error(r)
    Message.error('下载文件出现错误，请联系管理员！')
    downloadLoadingInstance.close()
  })
}

export default service
