/**
 * @description: axios封装 - 请求拦截、相应拦截、错误统一处理
 * @param {*}
 * @return {*}
 */
 import axios from 'axios';
 import { Loading, Message } from 'element-ui';
 import store from "../store";
 import _ from 'lodash';
 import router from "../router";
 import qs from "qs";
 import projectConfig from "./projectConfig";
 
 // loading对象
 let loadingInstance;
 
 // 请求合并只出现一次loading
 // 当前正在请求的数量
 let loadingRequestCount = 0;
 
 // 请求超时时间
 axios.defaults.timeout = 10000;
 
 //创建一个axios 实例
 const service = axios.create({
    //  baseURL: projectConfig.netHost,
     // baseURL: 'https://lz.dev.trydotec.com:8416/miniapp',
     timeout: 30000,
 });
 
 // 请求拦截器
 service.interceptors.request.use(
     config => {
         let loadingTarget = '#app';
        //  console.log('request拦截器config参数：', config)
         if(config.loadingTarget){
             loadingTarget = config.loadingTarget
         }
         let target = document.querySelector(loadingTarget);
         if(target && !config.hideLoading){
             // 请求拦截进来调用显示loading效果,默认都有loading效果
             showLoading(loadingTarget);
         }
         let token = sessionStorage.getItem('token')
        //  console.log('获取token',token)
        //  let token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI2M2Q1OTYxZi1mMTYzLTRjMWYtYjJkYy1iMzFiMjQ5YzA3ZTMiLCJpYXQiOjE2NjE5MjgzODEsImlzcyI6ImFkbWluIiwiYXVkIjoiMiIsInBsYXlsb2FkIjp7ImFyZWFDb2RlIjpudWxsLCJ0ZW5hbnRLZXkiOiJ0ZW5hbnQtMDAwMSIsImRlcHRJZCI6IjEiLCJkaWdlc3QiOm51bGwsIm5hbWUiOiIlRTclOTQlOTglRTclQjQlQTAlRTclOEYlOEQiLCJ1c2VySWQiOiIyIiwidXNlcm5hbWUiOiJnYW5zdXpoZW4ifSwiZXhwIjoxNjYyNjEyMzgxfQ.3GeuL01sIJ6JLbJr4rIz8lHJdtjZVDf9y4hMh_p0If8'
         // 身份令牌
         token && (config.headers['Authorization'] = token)
         return config;
     },
     (error) => {
         hideLoading()
         Promise.error(error)
     }
 )
 
 // 响应拦截器
 service.interceptors.response.use(
     response => {
         setTimeout(() => {
             hideLoading()
         }, 200);
         console.log('请求返回结果：', response)
         
         // 处理Blob格式的数据
         const res = response.data
         if(res instanceof Blob) {
             return new Promise((resolve, reject) => {
                 const reader = new FileReader()
                 reader.readAsText(res)
                 reader.onload = (e) => {
                     const { result } = e.target
                     if (result.code) {
                         // todo 此处，需要统一对错误做处理
                         // Message.closeAll()
                         // Message({ message: result.message, showClose: true, type: "error" })
                         reject(dealResponseError(result))
                     } else {
                         resolve(response)
                         console.log('请求返回结果11111：', response)
                     }
                 }
             })
         }else if(res.code) {
             return new Promise((resolve, reject) => {
                 if(res.code === 9200) {
                     resolve(res.data)
                 }else{
                     // todo 此处，需要统一对错误做处理
                     reject(dealResponseError(res));
                 }
             })
 
         }
 
         // return Promise.resolve(response.data);
     },
     error => {
         console.log('请求报错：', error)
         // todo 此处，需要统一对错误做处理
        
        if(error.response.status == 401) {
            Message.closeAll()
            setTimeout(() => {
                hideLoading()
            }, 200);
            // 登录过期&token存在，此时有提示
            Message({ message: '请求要求用户的身份认证', type: "error",customClass:'messageZindex'})
            store.state.token = '';
            sessionStorage.removeItem('token');
            sessionStorage.removeItem('userInfo');
            store.state.userinfo = {};
            store.state.routes = [];
            setTimeout(() => {
                router.push('/login')
            }, 300)
        }
        else
        {
            Message.closeAll()
            Message.error(`请求错误: ${error}`)
            setTimeout(() => {
                hideLoading()
            }, 200);
            if(error.response.status) {
                return Promise.reject(error.response);
            }
        }
     }
 );
 
 
 // 显示loading的函数 并且记录请求次数 ++
 const showLoading = (target) => {
     if(loadingRequestCount === 0) {
         loadingInstance = Loading.service({
             lock: true,
             text: '加载中...',
             target: target || 'body'
         });
     }
     loadingRequestCount++;
 }
 
 // 隐藏loading的函数，并且记录请求次数
 const hideLoading = () => {
     if(loadingRequestCount <= 0) return;
     loadingRequestCount--;
     if(loadingRequestCount === 0) {
         toHideLoading();
     }
 }
 
 // 防抖：将 300ms 间隔内的关闭 loading 便合并为一次. 防止连续请求时, loading闪烁的问题。
 var toHideLoading = _.debounce(() => {
     loadingInstance.close();
     loadingInstance = null;
 }, 300);
 
 const dealResponseError = (error) => {
     let code = error.code ||''
     let msg = error.msg || ''
     switch (code) {
         case 9400:
             break;
         case 9401:
             msg = "当前登录已失效，请重新登录!"
             break;
         case 9403:
             msg = "登陆令牌失效!"
             break;
         case 400:
             msg = "客户端请求的语法错误，服务器无法理解!"
             break;
         case 401:
             msg = "请求要求用户的身份认证!"
             break;
         case 403:
             msg = "服务器理解请求客户端的请求，但是拒绝执行此请求!"
             break;
         case 404:
             msg = "找不到资源（网页）!"
             break;
         case 405:
             msg = "客户端请求中的方法被禁止!"
             break;
         case 500:
         case 9500:
             msg = "服务器内部错误，无法完成请求!"
             break;
         case 503:
             msg = "充当网关或代理的服务器，未及时从远端服务器获取请求!"
             break;
         default:
             msg = "网络出错！";
             break;
     }
     console.log('错误处理----code:', code, '----msg----:', msg)
     Message.closeAll()
     // todo  不知道能否预防多个请求都返回登录失效的情况，提示只有1个
     if(code === 9401 || code === 9403) {
         // 登录过期&token存在，此时有提示
         Message({ message: msg, type: "error",customClass:'messageZindex' })
         store.state.token = '';
         sessionStorage.removeItem('token');
         sessionStorage.removeItem('userInfo');
         store.state.userinfo = {};
         store.state.routes = [];
         setTimeout(() => {
             router.push('/login')
         }, 300)
     }else{
         Message({ message: msg, type: "error",customClass:'messageZindex'})
     }
 
     let errorInfo = new Error(msg)
     errorInfo.code = code
     return errorInfo
 }
 // /**
 //  * post方法，对应post请求
 //  * @param {String} url [请求的url地址]
 //  * @param {Object} params [请求时携带的参数]
 //  */
 // export function post (url, params) {
 //     return new Promise((resolve, reject) => {
 //         axios.post(url, QS.stringify(params))
 //             .then(res => {
 //                 resolve(res.data);
 //             })
 //             .catch(err => {
 //                 reject(err.data)
 //             })
 //     });
 // }
 //
 // /**
 //  * get方法，对应get请求
 //  * @param {String} url [请求的url地址]
 //  * @param {Object} params [请求时携带的参数]
 //  */
 // export function get (url, param) {
 //     return new Promise((resolve, reject) => {
 //         axios.get(url, { params: params })
 //             .then(response => {
 //                 resolve(response.data)
 //             }, err => {
 //                 reject(err)
 //             })
 //             .catch((error) => {
 //                 reject(error)
 //             })
 //     })
 // }
 const download = (url, method = "get", param, customConfig) => {
    let obj = {};
    if (method === "get") {
      obj.params = param;
    } else {
      obj.data = param;
    }
    return new Promise((resolve, reject) => {
      service({
        method: method,
        url,
        ...obj,
        responseType: "blob",
      })
        .then((res) => {
          resolve(res);
        })
        .catch((error) => {
          reject(error);
        });
    });
  };
 
// export default service
 export default {
  service,
  postFile: (url, param, customConfig) =>download(url, "post", param, customConfig),
 }
 
 
 