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

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

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

function closeLoading() {
  if (needLoadingRequestCount <= 0) {
    return
  }
  needLoadingRequestCount--;
  if (needLoadingRequestCount === 0) {
    setTimeout(() => {
      if (loading) {
        loading.close()
      }
    }, 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)) {
      // console.log('-- cancel id:', item.id)
      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',
    lang: localStorage.getItem(SystemConfig.lang)
  },
  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 })
  });
  // console.log('-- request config:', config)
  return config;
}, (error) => {
  console.log(error);
  // 对请求错误做些什么
  return Promise.reject(error);
});

// 添加响应拦截器
service.interceptors.response.use((response) => {
  // 对响应数据做点什么
  // 请求成功后移除记录
  removePendingRequestRecord(response.config);
  const { data } = response;
  let result = JSON.parse(decrypt(data));
  console.log(response.config.url + ' = ', result, response.config);
  closeLoading();
  const { code, msg } = result;
  if (code && code !== 200) {
    // `token` 过期或者账号已在别处登录
    if (code === 401 || code === 4001) {
      Message.error(msg || '系统异常， 请联系管理员');
    }
    if (code === 2013 || code === 2014) {
      // 清除浏览器全部临时缓存
      Session.clear();
      router.push('/login').then(r => console.log(r));
      store.commit('setMenuData', {});
      // resetRouter(); // 重置路由
      Message.error("你已被登出，请重新登录");
    }
    return result
  } else {
    return result;
  }
}, (error) => {
  closeLoading();
  // 对响应错误做点什么
  if (error.message.indexOf('timeout') !== -1) {
    Message.error('网络超时');
  } else if (error.message === 'Network Error') {
    Message.error('网络连接错误');
  } else {
    Message.error(error.response.data.message || '系统异常， 请联系管理员');
  }
  return Promise.reject(error);
});

// 导出 axios 实例
export default service;
