import axios from 'axios';
import qs from 'qs';
import { Message } from 'element-ui';
import store from '@/store';
import { getToken, setToken } from '@/utils/auth';

/**
 * 设置全局参数
 */
axios.defaults.baseURL = process.env.VUE_APP_BASE_API;
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8'
// axios.defaults.withCredentials = true
axios.defaults.timeout = process.env.VUE_APP_API_TIMEOUT;

// create an axios instance
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  // withCredentials: true, // send cookies when cross-domain requests
  timeout: 5000 // request timeout
});

// request interceptor
axios.interceptors.request.use(
  config => {
    // do something before request is sent
    if (store.getters.token) {
      // let each request carry token
      // ['X-Token'] is a custom headers key
      // please modify it according to the actual situation
      config.headers['token'] = getToken();
    }
    return config;
  },
  error => {
    // do something with request error
    console.log(error); // for debug
    return Promise.reject(error);
  }
);

// response interceptor
axios.interceptors.response.use(
  /**
   * If you want to get http information such as headers or status
   * Please return  response => response
   */

  response => {
    const res = response.data;
    if (res.code === 401) {
      setToken();
      // 045 登录态失效,重定向到登录页 更改地址
      location.replace(`https://youxiangle.cn/yxl-admin/#/login`);

      Message({
        message: 'Token失效,请重新登陆',
        type: 'error',
        duration: 5 * 1000
      });
      return Promise.reject(new Error(''));
    }
    return res;
  },
  error => {
    console.log('错误 response', error);
    return Promise.reject(error);
  }
);

// 预处理配置文件
const pretreatConfig = _config => {
  if (_config && 'dataType' in _config) {
    if (_config.dataType === 'json') {
      Object.assign(_config, {
        headers: {
          'Content-Type': 'application/json;charset=UTF-8'
        }
      });
    } else if (_config.dataType === 'formdata') {
      Object.assign(_config, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        }
      });
    }
  }
  if (
    process.env.NODE_ENV !== 'production' &&
    _config &&
    'mock' in _config &&
    _config.mock
  ) {
    Object.assign(_config, {
      baseURL: process.env.VUE_APP_BASE_API_MOCK
    });
  }
  return _config;
};

/**
 * 处理response
 * @param {axios请求结果} fetchResult
 */
const formatResponse = fetchResult =>
  fetchResult
    .then(response => formatStatus(response))
    .then(res => formatCode(res), handleNetworkError);

/**
 * 格式化status
 */
const formatStatus = response => {
  // 如果http状态码正常,则直接返回数据
  if (response && response.code === 200) {
    response.success = true;
    return response;
    // 如果不需要除了data之外的数据,可以直接 return response.data
  }
  // console.warn('---------------2-----------------')
  // console.warn(response)
  let txt = '网络异常';
  if (!response) {
    txt = '通信错误';
  } else if (response.code === 500) {
    txt = response.msg || '服务器错误';
    // } else if (response.code === 401) {
    //   txt = '身份验证失败'
  } else if (response.code === 100000) {
    txt = response.msg || '服务器错误';
  }
  Message({
    message: txt || 'Error',
    type: 'error',
    duration: 5 * 1000
  });
  // 异常状态下,把错误信息返回去
  return {
    code: -404,
    msg: txt,
    request: response.request || {}
  };
};

/**
 * 格式化code
 */
const formatCode = ({ code, data, msg }) => {
  // 如果code异常(这里已经包括网络错误,服务器错误,后端抛出的错误),可以弹出一个错误提示,告诉用户
  if (code === -404) {
    return {
      code: code,
      success: false,
      msg,
      data: {}
    };
  }
  // // api内置错误类型
  // if (data && !data.success) {
  //   let msg = data.msg
  //   if (data.code === 500) {
  //     msg = '内部服务器错误'
  //   }
  //   return {
  //     success: false,
  //     msg,
  //     code: data.code,
  //     errorObj: data.error,
  //     data: {}
  //   }
  // }
  return {
    success: code === 200,
    msg,
    code,
    data
  };
};

// 处理网络通信错误
const handleNetworkError = error => {
  if (error) {
    if (error.response && error.response.status === 500) {
      return {
        code: 500,
        success: false,
        msg: '通信错误',
        data: {}
      };
    } else if (error.response && error.response.status === 401) {
      store.dispatch('user/resetToken');
      setToken();
      // location.replace(`http://wxhd.lifespaceprobiotics.cn/code/admin/#/login`);
    }
    if (error.message.includes('timeout')) {
      return {
        code: 1,
        success: false,
        msg: '通信超时',
        data: {}
      };
      // } if (error.msg.includes('404')) {
      //   return {
      //     code: 1,
      //     success: false,
      //     msg: '通信失败',
      //     data: {}
      //   }
    }
  }
  return {
    code: -1,
    success: false,
    msg: '',
    data: {}
  };
};

/* 暂时不需要下载 要调整 */
// const formatDownload = (fetchResult, name = '压缩文件') => fetchResult
//   .then(response => {
//     const filename = `${name}.zip`
//     const blob = response
//     if (typeof window.navigator.msSaveBlob !== 'undefined') {
//       // IE workaround for "HTML7007: One or more blob URLs were
//       // revoked by closing the blob for which they were created.
//       // These URLs will no longer resolve as the data backing
//       // the URL has been freed."
//       window.navigator.msSaveBlob(blob, filename)
//     } else {
//       const blobURL = window.URL.createObjectURL(blob)
//       const tempLink = document.createElement('a')
//       tempLink.style.display = 'none'
//       tempLink.href = blobURL
//       tempLink.setAttribute('download', filename)

//       // Safari thinks _blank anchor are pop ups. We only want to set _blank
//       // target if the browser does not support the HTML5 download attribute.
//       // This allows you to download files in desktop safari if pop up blocking
//       // is enabled.
//       if (typeof tempLink.download === 'undefined') {
//         tempLink.setAttribute('target', '_blank')
//       }

//       document.body.appendChild(tempLink)
//       tempLink.click()
//       document.body.removeChild(tempLink)
//       window.URL.revokeObjectURL(blobURL)
//     }
//     //   Message({
//     //     message: '请求下载文件失败,请稍后重试~',
//     //     type: 'error',
//     //     duration: 5 * 1000
//     //   })
//     // }
//   })

const get = (url, data = {}, config) => {
  config = pretreatConfig(config);
  return formatResponse(
    axios.get(url, {
      ...config,
      params: data,
      paramsSerializer(params) {
        return qs.stringify(params, {
          arrayFormat: 'brackets'
        });
      }
    })
  );
};

const del = (url, data = {}, config, type) => {
  config = pretreatConfig(config);
  return formatResponse(
    axios.delete(url, {
      ...config,
      params: data,
      paramsSerializer(params) {
        return qs.stringify(params, {
          arrayFormat: 'brackets'
        });
      }
    })
  );
};

const delData = (url, data = {}, params, config) => {
  config = pretreatConfig(config);
  return formatResponse(
    axios.delete(url, {
      ...config,
      data: data,
      params: params,
      paramsSerializer(params) {
        return qs.stringify(params, {
          arrayFormat: 'brackets'
        });
      }
    })
  );
};

const post = (url, data = {}, config) => {
  config = pretreatConfig(config);
  config = Object.assign(
    {
      headers: {
        'Content-Type': 'application/json; charset=UTF-8'
      }
    },
    config
  );
  return formatResponse(
    axios.post(
      url,
      {
        data,
        seq: config.seq,
        token: config.token,
        limit: data.limit,
        start: data.start
      },
      config
    )
  );
};

const postData = (url, data = {}, config) => {
  config = pretreatConfig(config);
  config = Object.assign(
    {
      headers: {
        'Content-Type': 'multipart/form-data; charset=UTF-8'
      }
    },
    config
  );
  return formatResponse(axios.post(url, data, config));
};

const put = (url, data = {}, config) => {
  config = pretreatConfig(config);
  config = Object.assign(
    {
      headers: {
        'Content-Type': 'application/json; charset=UTF-8'
      }
    },
    config
  );
  return formatResponse(
    axios.put(url, { data, seq: config.seq, token: config.token }, config)
  );
};

/* 上方注释函数 */
// export const download = (url, data = {}, config, name) => {
//   config = pretreatConfig(config)
//   config = Object.assign({
//     headers: {
//       'Content-Type': 'application/json'F
//     },
//     responseType: 'blob'
//   }, config)
//   // return formatDownload(axios.post(url, data, config), name)
//   return formatDownload(axios.post(url, data, config), name)
// }

// export default axios;
export default {
  get,
  post,
  postData,
  del,
  put,
  delData
  // download
};