/* 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');
    const pandaPublish = localStorage.getItem('panda-publish');
    const getWay = '/PandaCore/GateWay';
    if (token) {
      request.headers.Authorization = 'Bearer ' + token;
    }
    if (pandaPublish) {
      console.log(request.url, 'request.url');
      if (
        request.url != '/PandaOMS/OMS/OMSLogin' &&
        request.url != '/Publish/OMS/FileCenter/SaveMobileApk' &&
        request.url != '/PandaOMS/OMS/HostManager/GetGateWay' &&
        !request.url.includes('/PandaCore/GateWay/')
      )
        request.url = getWay + request.url;
    }
    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);
  }
};
