import Vue from "vue";
import VueRouter from "vue-router";
import store from "@/store";
import routes from "./routes";
import { parseSearch } from "@/service/utils";
import { isXyqb, isWeixinBrower } from "@/service/validation";
import cfg from "@/config";
import { getUserInfoByXyqb, getwxOpenId } from "@/api/user";
import localStorage from "@/service/localStorage";
import goodsList from "@/api/goodsList.mock";
import { getShare } from "@/api/shareInfo";
import { debounce } from "lodash-es";

Vue.use(VueRouter);

const originalPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return originalPush.call(this, location).catch(err => err);
};
VueRouter.prototype.replace = function push(location) {
  return originalPush.call(this, location).catch(err => err);
};

const getShareInfo = debounce(function(to) {
  getShare(to);
}, 300);

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
  scrollBehavior() {
    return { x: 0, y: 0 };
  }
});

router.beforeEach((to, from, next) => {
  const urlParams = parseSearch(window.location.href);
  setTitle(to.meta.title, to.path, to.query);
  setChannelId(urlParams);
  if (isXyqb) getAuthInfo(urlParams.vccToken || urlParams.token);
  if (isWeixinBrower) {
    getWxOpenId(urlParams.code);
    getShareInfo(to);
  }
  next();
});

// 路由异常错误处理，尝试解析一个异步组件时发生错误，重新渲染目标页面
router.onError(error => {
  console.log("router error:", error.message);
  const pattern = /Loading chunk/g;
  const isChunkLoadFailed = error.message.match(pattern);
  const targetPath = router.history.pending.fullPath;
  if (isChunkLoadFailed) {
    router.replace(targetPath);
  }
});

async function getAuthInfo(xyqbToken) {
  if (localStorage.get("xyqbAuthState") == 2) {
    store.dispatch("setAuthXyqb", 1);
  }
  if (!xyqbToken || xyqbToken === localStorage.get("xyqbToken")) return;
  const res = await getUserInfoByXyqb({ xyqbToken });
  if (res) {
    localStorage.set("xyqbUserInfo", res);
    localStorage.set("xyqbToken", xyqbToken);
  }
}

async function getWxOpenId(code) {
  // code只能用一次
  if (!code || code === sessionStorage.getItem("latestCode")) return;
  sessionStorage.setItem("latestCode", code);
  const res = await getwxOpenId({ code, appId: cfg.wxAppId });
  // 切换账号时清除缓存
  if (localStorage.get("openId") && res.openId !== localStorage.get("openId")) {
    console.log("切换账号");
    localStorage.clear();
  }
  localStorage.set("openId", res.openId);
}

function setTitle(title, path, query) {
  if (path === "/goods/detail") {
    const goods = goodsList.find(v => v.id === query.id);
    title = goods.title;
  }
  document.title = title;
  // 如果是 iOS 设备，则使用如下 hack 的写法实现页面标题的更新
  if (navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) {
    const hackIframe = document.createElement("iframe");
    hackIframe.style.display = "none";
    hackIframe.src = "/public/fixIosTitle.html?r=" + Math.random();
    document.body.appendChild(hackIframe);
    setTimeout(() => {
      document.body.removeChild(hackIframe);
    }, 300);
  }
}

function setChannelId(params) {
  if (params.channelId) {
    localStorage.set("channelId", params.channelId);
  }
}

export default router;
