import axios from 'axios';
import qs from "qs";
import CmsLoading from "@/comps/CmsLoading";
import SystemConfig from '@/utils/SystemConfig'
import { decrypt, encrypt } from '@/utils/aes-encrypt'
import { Message } from 'element-ui';
import { Cookies, Session } from '@/utils/storage';
import messageTips from '@/utils/messageTips';

let needLoadingRequestCount = 0; //当前正在请求的数量
let loading = undefined;

function showLoading() {
  if (needLoadingRequestCount === 0 && !loading) {
    loading = CmsLoading.open()
  }
  needLoadingRequestCount++
}

function closeLoading() {
  if (needLoadingRequestCount > 0) {
    needLoadingRequestCount--;
  }
  if (needLoadingRequestCount === 0) {
    setTimeout(() => {
      if (loading) {
        loading.close();
        loading = undefined;
      }
    }, 100)
  }
}

/**
 * 正在进行（pending 状态）的请求记录
 */
// 记录所有正在进行（pending 状态）的请求的 "唯一值" 和 "取消请求方法"
const allPendingRequestsRecord = [];

/**
 * 通过请求的 url 和 method 来标示请求唯一值
 * @param {*} config 配置信息
 * @returns
 */
function getUniqueId(config) {
  return `url=${ config.url }&method=${ config.method }`
}

/**
 * 取消请求，并移除记录
 * @param {*} config 配置信息
 */
function removePendingRequestRecord(config) {
  allPendingRequestsRecord.some((item, index) => {
    if (item.id === getUniqueId(config)) {
      item.cancel(); // 取消请求
      allPendingRequestsRecord.splice(index, 1);// 移除记录
      return true
    }
  })
}

// 创建 axios 实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 100000,
  //  http  请求头封装
  headers: {
    'Content-Type': 'application/json;charset=utf-8',
    'language': localStorage.getItem(SystemConfig.language),
  },
  withCredentials: true, // default
  responseEncoding: 'utf8', // default
  // 跨域认证信息 header 名;
  xsrfHeaderName: 'Authorization',
  xsrfCookieName: SystemConfig.token,
  paramsSerializer: function (params) {
    return qs.stringify(params, { arrayFormat: 'brackets' })
  },
});

// 添加请求拦截器
service.interceptors.request.use((config) => {
  // 在发送请求之前做些什么 token
  if (Session.get(SystemConfig.token)) {
    // config.headers.common['Authorization'] = `${ Session.get(SystemConfig.token) }`;
    config.headers.common[SystemConfig.token] = `${ Session.get(SystemConfig.token) }`;
  }
  if (config['loading']) {
    showLoading()
  }
  // matchersUrl(config);
  // 在 get 请求上带上时间戳
  if (config.method === 'get') {
    config.url = config.url + '?' + new Date().getTime()
  }
  // 通过添加随机 uniqueCancel 值，确保每个请求具有唯一标示
  // config.url = `${ config.url }?unique=uniqueCancel_${ Math.random().toString(36).substr(2) }`;
  // 在请求发送前执行一下取消操作，防止重复发送请求（dashboard 类似页面具有重复多次的相同请求，所有不能在全局做防止重复）
  removePendingRequestRecord(config);
  // 设置请求的 cancelToken
  config.cancelToken = new axios.CancelToken(function executor(cancel) {
    // 添加记录，记录请求的唯一值和取消方法
    allPendingRequestsRecord.push({ id: getUniqueId(config), cancel })
  });
  if (!Cookies.get(SystemConfig.secretKey)) {
    Cookies.set(SystemConfig.secretKey, SystemConfig.secretValue);
  }
  if (!config['uploadFile']) {
    config.data = JSON.stringify({
      token: Cookies.get(SystemConfig.token),
      time: new Date().getTime(),
      data: SystemConfig.requestDataEncrypt ? encrypt(JSON.stringify(config.data)) : config.data,
      isDecrypt: SystemConfig.requestDataEncrypt
    });
  } else {
    config.headers.common['uplaodFile'] = true;
  }
  return config;
}, (error) => {
  // 对请求错误做些什么
  return Promise.reject(error);
});

// 添加响应拦截器
service.interceptors.response.use((response) => {
  // 对响应数据做点什么
  // 请求成功后移除记录
  removePendingRequestRecord(response.config);
  const { data } = response;
  let result = data;
  if (response.config['encrypt']) {
    result = JSON.parse(decrypt(data));
  }
  console.log(response.config.url + ' = ', result, response.config);
  setTimeout(() => {
    closeLoading();
  }, 300)
  const { code, msg } = result;
  if (code && code !== 200) {
    // `token` 过期或者账号已在别处登录
    if (code === 2013 || code === 2014 || code === 401 || code === 4001) {
      // 清除浏览器全部临时缓存
      Session.clear();
      Cookies.remove(SystemConfig.token);
      messageTips.alert(msg, () => {
        const host = window.location.host;
        const protocol = window.location.protocol;
        const url = `${ SystemConfig.loginPage ? SystemConfig.loginPage : '' }`;
        const loginPage = `${ protocol }//${ host }` + (url ? url : "");
        if (window !== top) {
          top.location.href = loginPage;
        } else window.location.href = loginPage;
      })
    }
    return result
  } else {
    return result;
  }
}, (error) => {
  closeLoading();
  // 对响应错误做点什么
  if (error.message && error.message.indexOf('timeout') !== -1) {
    Message.error('网络超时');
  } else if (error.message === 'Network Error') {
    Message.error('网络连接错误');
  } else {
    if (error.response && error.response.data)
      Message.error(error.response.data.message || '系统异常， 请联系管理员');
  }
  return Promise.reject(error);
});

// 导出 axios 实例
export default service;
