import Vue from "vue";
import axios from "axios";
import { loadProgressBar } from "./axiosProgress";
import cachingGet from "./axiosCache";
import { Message, Modal } from "iview";
import router from "../router";
//axios配置 start

const qmInstance = axios.create({});

//请求拦截

/**
 * A. token lifecycle
 * 1. /login UI => localStorage.removeItem('token') && localStorage.setItem('token')
 * 2. non /login UI => axios if(!wk_token) wk_token = window.sessionStorage.getItem("token"), send request
 * 3. if axios request fail with 401/403, wk_token = null, redirect to /login removeItem('token')
 * 4. logout to /login, before send request, invalidate wk_token
 * */

let wk_token, wk_key;
qmInstance.interceptors.request.use(
  config => {
    // debugger;
    if (
      config.url.includes("/login") === false ||
      config.url.includes("/api/ecs_core/auth/thirdPartyStudentAccess") ===
        false
    ) {
      // if (!wk_token) {
      wk_token = window.sessionStorage.getItem("token");
      wk_key = window.localStorage.getItem("key");
      // }
      if (wk_token && config.headers.common["token"] == null) {
        config.headers.common["token"] = wk_token;
        // Axios.defaults.headers.common["key"] = window.localStorage.getItem("key");
        config.headers.common["key"] = wk_key;
      }
    } else {
      wk_token = null;
    }

    return config;
  },
  error => {
    Message.error({
      content: error,
      duration: 15,
      closable: true,
    });
    return Promise.resolve(error);
  }
);

//响应拦截
qmInstance.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    if (!error.response) {
      // "Network Error" 网络不通，直接返回
      // "timeout of 30000ms exceeded" 连接超时，可能是客户端原因，也可能是服务器原因
      if (
        window.___lastNetworkError === undefined ||
        window.___lastNetworkError < Date.now() - 15 * 1000
      ) {
        Message.error({
          content: "网络连接异常，请检查网络设置。",
          duration: 15,
          closable: true,
        });
        window.___lastNetworkError = Date.now();
      }

      // TODO: 由于chrome58不支持navigator.connection.downlink , 所以无法判断客户端网络状况

      let detailInfo = "";
      try {
        (detailInfo += error.config.url
          .replace(/=\w*/g, "=")
          .replace(/\/\d+\//g, "/{id}/")
          .replace(/\/\d+$/g, "/{id}")) +
          " ||| " +
          error.message;
      } catch (error) {
        console.log("detailInfo error");
      }

      window._hmt.push([
        "_trackEvent",
        location.pathname.replace(/\d+/g, ""),
        "网络连接异常，请检查网络设置。",
        detailInfo,
      ]);

      return Promise.reject(error);
    }
    // 这里是返回状态码不为200时候的错误处理
    let status = error.response.status;

    // 登录失效 跳转登录页面
    if (status == 403 || status == 401) {
      if (
        window.___lastInvalidDate === undefined ||
        window.___lastInvalidDate < Date.now() - 1000
      ) {
        Message.error({
          content: "登录失效，请重新登录！",
          duration: 15,
          closable: true,
        });
        window.___lastInvalidDate = Date.now();

        const redirectUrl = sessionStorage.getItem("redirectUrl");
        if (redirectUrl) {
          Modal.error({
            title: "确认返回",
            content: "token失效",
            onOk: () => {
              window.location = redirectUrl;
            },
          });
        } else {
          router.push("/login/" + localStorage.getItem("domain"));
        }
      }
      wk_token = null;
      // router.push("/login/" + localStorage.getItem("domain"));
      return; // 仅显示登录失效，不显示因登录失效造成的后续错误
    } else if (status == 502) {
      window._hmt.push([
        "_trackEvent",
        location.pathname,
        "服务器异常(502)！",
        error.config.url,
      ]);
      Message.error({
        content: "服务器异常(502)！",
        duration: 15,
        closable: true,
      });
      return Promise.reject(error);
    } else if (status == 503) {
      const deal503Apis = [
        "/api/ecs_oe_student/examControl/checkExamInProgress",
        "/api/ecs_oe_admin/examControl/queryExamList",
      ];
      if (deal503Apis.includes(error.config.url)) {
        return Promise.resolve({ status: 503 });
      }
      window._hmt.push([
        "_trackEvent",
        location.pathname.replace(/\d+/g, ""),
        "服务器繁忙(503)！请稍后重试。",
        error.config.url.replace(/\d+/g, ""),
      ]);
      Message.error({
        content: "服务器繁忙(503)！请稍后重试。",
        duration: 15,
        closable: true,
      });
      return Promise.reject(error);
    } else if (status != 200) {
      window._hmt.push([
        "_trackEvent",
        location.pathname.replace(/\d+/g, ""),
        "status: " + status,
        error.config.url
          .replace(/=\w*/g, "=")
          .replace(/\/\d+\//g, "/{id}/")
          .replace(/\/\d+$/g, "/{id}"),
      ]);
      if (
        wk_token &&
        ![401, 403].includes(status) &&
        !error.config.url.includes("/api/ecs_core/log/studentClient/")
      ) {
        setTimeout(() => {
          qmInstance.post(
            "/api/ecs_core/log/studentClient/" + "debug/S-009001",
            error.config.url + " 请求失败",
            {
              headers: {
                "Content-Type": "text/plain",
              },
            }
          );
        }, 3 * 1000);
      }

      const data = error.response.data;
      if (data && data.desc) {
        Message.error({
          content: data.desc,
          duration: 15,
          closable: true,
        });
      } else {
        Message.error({
          content: "未定义异常: " + JSON.stringify(data, 2),
          duration: 15,
          closable: true,
        });
      }
    }

    return Promise.reject(error);
  }
);

qmInstance.defaults.withCredentials = true; //允许跨域携带cookie
qmInstance.defaults.timeout = 30 * 1000; //超时时间
qmInstance.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; //标识这是一个 ajax 请求

qmInstance.get = cachingGet(qmInstance.get, [
  /\/api\/exam_question\/question\/\?question_id/,
  /\/api\/exam_question\/paper_struct\/\?exam_record_id=/,
  /\/api\/ecs_oe_student\/examQuestion\/getQuestionContent\?questionId=.*&exam_record_id=/,
  // /\/api\/ecs_exam_work\/exam\/\d+$/,
  // /\/api\/ecs_oe_student_face\/upyun$/,
  /\/api\/ecs_oe_student\/examFaceLivenessVerify\/checkFaceLiveness$/,
]);
loadProgressBar(qmInstance);

// const upyunInstance = axios.create({});
// FIXME: axios bug. wait 0.19 release. https://github.com/axios/axios/issues/385
// upyunInstance.defaults.headers.common = {};
// // upyunInstance.defaults.headers.common["Authorization"] = UPYUN_HEADER_AUTH;

// let __upyunAuth = null;
// let __upyunBucketUrl = null;
// upyunInstance.interceptors.request.use(
//   config => {
//     if (__upyunAuth) {
//       config.baseURL = __upyunBucketUrl;
//       config.headers.common["Authorization"] = __upyunAuth;
//       return config;
//     } else {
//       return qmInstance
//         .get("/api/ecs_oe_student_face/upyun")
//         .then(res => {
//           __upyunBucketUrl = res.data.bucketUrl;
//           config.baseURL = __upyunBucketUrl;
//           const authorization =
//             "Basic " +
//             btoa(atob(res.data.upyunOperator) + ":" + atob(res.data.upyunCred));
//           __upyunAuth = authorization;
//           config.headers.common["Authorization"] = __upyunAuth;
//           return config;
//         })
//         .catch(err => {
//           console.log(err);
//         });
//     }
//   },
//   error => {
//     Message.error({
//       content: error,
//       duration: 10,
//       closable: true
//     });
//     return Promise.resolve(error);
//   }
// );

// loadProgressBar(upyunInstance);

Vue.prototype.$http = qmInstance;
// Vue.prototype.$upyunhttp = upyunInstance;
export default {
  install: function(Vue) {
    Object.defineProperty(Vue.prototype, "$http", {
      value: qmInstance,
    });
    // Object.defineProperty(Vue.prototype, "$upyunhttp", {
    //   value: upyunInstance
    // });
  },
};
