/* eslint-disable  */
import axios from 'axios';
import assign from 'lodash/assign';
import toLower from 'lodash/toLower';
// import isArray from 'lodash/isArray';
// import isArrayLikeObject from 'lodash/isArrayLikeObject';
import isFunction from 'lodash/isFunction';
import extendConfig from './defaultConfig';
const globalConfig = {
  bizRedirectHandler: extendConfig.bizRedirectHandler
}
const globalConfigMatchers = [];
/* no-unused-vars */
const getMatchedConfig = requestConfig => {
  if (!globalConfigMatchers.length) {
    return null;
  }
  for (let i = 0, len = globalConfigMatchers.length; i < len; i += 1) {
    const [matcher, extendConfig] = globalConfigMatchers[i];
    // 匹配到第一个matcher就返回了, 存在后续配置不生效的情况
    if (matcher(requestConfig)) {
      console.log(`matched url: ${requestConfig.url}`)
      return extendConfig;
    }

    return null;
  }
};
axios.defaults.withCredentials = true
axios.interceptors.request.use( function (request){
  const token = localStorage.getItem('token')
  if(token){
    request.headers.Authorization = 'Bearer ' + token
  }
  return request
}, function (error) {
  // Any status codes that falls outside the range of 2xx cause this function to trigger
  // Do something with response error
  return Promise.reject(error);
})
axios.interceptors.response.use(function (response) {
  return response
}, (error) => {
  if (error.response) {
    switch (error.response.status) {
      case 401:
        globalConfig.bizRedirectHandler(error.response)
    }
  }
  return Promise.reject(error);
})

export const request = (config, ctx) => {
  const {
    url,
    method = 'GET',
    params,
    convertParams,
    converter,
    successMessage,
    ...restAxiosConfig
  } = config;

  let requestOptions = {
    ...restAxiosConfig,
    url,
    method,
  };

  const matchedConfig = getMatchedConfig(requestOptions);

  const curConf = assign({}, globalConfig, matchedConfig);

  const {
    bizRedirectHandler,
    bizDevErrorAdapter,
    bizErrorMessageAdapter,
    bizSuccessMessageAdapter,
    bizNotifyHandler,
    bizDataAdapter,
    bizParamsAdapter,
    bizRequestAdapter,
  } = curConf;

  let finalParams = params || {};

  if (bizParamsAdapter) {
    finalParams = bizParamsAdapter(finalParams);
  }

  const lMethod = toLower(method);

  if (lMethod === 'get' || lMethod === 'delete') {
    requestOptions.params = finalParams;
  } else {
    requestOptions.data = finalParams;
  }

  if (bizRequestAdapter) {
    requestOptions = bizRequestAdapter(requestOptions);
  }

  return axios(requestOptions).then(raw => raw && raw.data)
    .then(
      res =>
        new Promise((resolve, reject) => {
          // 1. 重定向
          if (bizRedirectHandler) {
            bizRedirectHandler(res);
          }

          // 2. 开发级别信息转换
          const errorDesc = bizDevErrorAdapter ? bizDevErrorAdapter(res) : null;

          // 3. 用户级错误信息转换
          const errorMsg = bizErrorMessageAdapter
            ? bizErrorMessageAdapter(res)
            : null;

          // 4. 成功信息转换
          const successMsg = bizSuccessMessageAdapter
            ? bizSuccessMessageAdapter(res, successMessage)
            : null;

          // 5. 消息处理
          if (bizNotifyHandler) {
            bizNotifyHandler({
              errorDesc,
              errorMessage: errorMsg,
              successMessage: successMsg,
            });
          }

          // 生产环境只有 errorMsg 起作用
          if (errorDesc || errorMsg) {
            return reject(errorDesc || errorMsg);
          }

          // 6. 数据转换
          const data = bizDataAdapter ? bizDataAdapter(res) : res;

          resolve(data);
        }),
    );
};

request.defaults = axios.defaults;

request.use = (matcherOrConfig, extendConfig) => {
  if (isFunction(matcherOrConfig)) {
    // 如果是函数,则把第二个参数作为满足matcher函数的配置,
    // 换言之,只在matcher执行返回true时,才应用extendConfig
    globalConfigMatchers.push([matcherOrConfig, extendConfig]);
  } else {
    // 如果不是函数,则matcher就是一个配置对象,放到全局配置中
    globalConfig = assign({}, globalConfig, matcherOrConfig);
  }
};