import Router from "vue-router";
import { whiteList as routeWhiteList } from "@/config/route";

function interopDefault(promise) {
  return promise.then((m) => m.default || m);
}

export function generateTabName(menuSuffix, meta, i18n, locale) {
  if (meta.combinationMenuName instanceof Array) {
    const suffix = menuSuffix?.split(",") || [];
    return meta.combinationMenuName
      .map((item) => {
        const label = i18n.t(item) || "";
        const repeat = suffix.find((suffixItem) =>
          label.toLocaleLowerCase().includes(suffixItem.toLocaleLowerCase())
        );
        if (!repeat) {
          return label;
        }
        const index = label
          .toLocaleLowerCase()
          .indexOf(repeat.toLocaleLowerCase());
        const tmp = [...label];
        tmp.splice(index, repeat.length);
        return tmp.join("").trim();
      })
      .join(["zh_CN", "zh_TW"].includes(locale) ? "" : " ");
  }
  if (meta.title) {
    return i18n.t(meta.title);
  }
  return undefined;
}

export const staticRoutes = [
  {
    path: "/",
    name: "home",
    component: () => interopDefault(import("~/pages/index")),
    meta: {
      title: "MENU:CORE:HOME",
      noCache: false,
      affix: true,
      icon: undefined,
    },
  },
  {
    path: "/personal-center",
    name: "personal-center",
    component: () => interopDefault(import("~/pages/personal-center")),
    meta: {
      title: "PERSONAL_CENTER",
      noCache: false,
      affix: false,
      icon: undefined,
    },
  },
  {
    path: "/messageCenter",
    name: "message-center",
    component: () =>
      interopDefault(import("~/pages/upms/service/message/messageCenter")),
    meta: {
      title: "MESSAGE_CENTER",
      noCache: false,
      affix: false,
      icon: undefined,
    },
  },
  {
    path: "/messageCenter/view",
    name: "message-center-view",
    component: () =>
      interopDefault(import("~/pages/upms/service/message/messageCenter/view")),
    meta: {
      title: "VIEW_DETAIL",
      noCache: false,
      affix: false,
      icon: undefined,
    },
  },
  {
    path: "/white-route/app-download",
    name: "app-download",
    component: () => interopDefault(import("~/pages/app-download")),
  },
  {
    path: "/login",
    name: "login",
    component: () => interopDefault(import("~/pages/login")),
  },
  {
    path: "/reset",
    name: "reset",
    component: () => interopDefault(import("~/pages/reset-password")),
  },
  {
    path: "/batch-import",
    name: "batch-import",
    component: () => interopDefault(import("~/pages/batch-import")),
    meta: {
      title: "BATCH_IMPORT",
      noCache: false,
      affix: false,
      icon: undefined,
    },
  },
  // 白名单路由处理：①需要token白名单路由②不需要token白名单路由
  // ①需要token白名单路由。正常配置。"一定不能" 以"/white-route"前缀开头
  // ②不需要token白名单路由。路由必须以"/white-route"前缀开头
  ...routeWhiteList,
  {
    path: "/external-view/:id?",
    name: "external-view-id",
    component: () => interopDefault(import("~/pages/external-view/_id")),
  },
  {
    path: "/redirect*",
    name: "redirect*",
    component: () => interopDefault(import("~/components/Redirect/index")),
  },
];

function generatePath(path) {
  let res = path.replace("views", "pages").replace(/\\/g, "/");
  res = res.startsWith("/") ? res.substr(1) : res;
  res = res.startsWith("pages") ? res : `pages/${res}`;
  res = /\.(vue|js)/.test(res) ? res.replace(/(\.vue)/, "") : res;
  return res.substr(6);
}

export function generateRouteKey(route) {
  return {
    key: route.id,
    keyPath: [
      ...(route.parentIds?.split(",") || []).filter(
        (e) => !["", "0"].includes(e)
      ),
      route.id,
    ],
  };
}

function generate(routes, router, parentMenuName = "") {
  routes.forEach((item) => {
    const map = {};
    map.name = "";
    map.id = item.id;
    map.path = item.menuPath;
    map.icon = item.icon;
    map.meta = {
      title: item.menuName?.trim(),
      cache: [1, "1"].includes(item.keepAlive),
      affix: item.menuPath === "/",
      ...generateRouteKey(item),
    };
    if (item.component) {
      const componentPath = generatePath(item.component);
      try {
        map.component = () =>
          interopDefault(
            import(`~/pages/${componentPath}.vue`).catch(() => {
              return import("~/layouts/error.vue");
            })
          );
      } catch (e) {}

      if (item.menuPath && item.isFrame !== "Y") {
        if (item.menuType === "BUTTON" && item.isRelated === "Y") {
          map.meta.combinationMenuName = item.menuTag
            ? [item.menuTag]
            : [map.meta.title, parentMenuName];
          router.addRoute(map);
        } else {
          router.addRoute(map);
        }
      }
    }
    if (item.children?.length) {
      generate(item.children, router, map.meta.title);
    }
  });
}

export default (context) => {
  const { app, store } = context;
  const { router } = app;
  router.matcher = new Router({
    ...router.options,
    routes: staticRoutes,
  }).matcher;

  router.beforeEach((to, _, next) => {
    // nextPath
    let toPath = to.path.endsWith("/")
      ? to.path.substr(0, to.path.length - 1)
      : to.path;
    toPath = toPath === "" ? "/" : toPath;
    // 有token
    const hasToken = Boolean(context.$auth.getToken("local"));
    const routes = router.getRoutes();
    // 判断是否只有静态路由
    const isOnlyStaticRoutes =
      routes.length === staticRoutes.length ||
      routes.findIndex((e) => e.path === "/redirect*") === -1;

    if (toPath.startsWith("/white-route")) {
      // 白名单路由
      next();
    } else if (["/login", "/license", "/reset"].includes(toPath)) {
      // 登录、授权重置路由
      if (!isOnlyStaticRoutes) {
        router.matcher = new Router({
          ...router.options,
          routes: staticRoutes,
        }).matcher;
      }
      next();
    } else if (store.state.account.isReset) {
      // 强制重置密码
      next({ path: "/reset" });
    } else if (!hasToken) {
      if (toPath === "/login") {
        next();
      } else {
        next({ path: "/login" });
      }
    } else if (!store.state.account.menus.length) {
      store
        .dispatch("fetchSysInfoByToken")
        .then(() => {
          isOnlyStaticRoutes &&
            store.state.account.menus.forEach((item) => {
              generate(item.children, router);
            });
          next({ ...to, replace: true });
        })
        .catch(() => {
          next({ path: "/login" });
        });
    } else if (isOnlyStaticRoutes) {
      store.state.account.menus.forEach((item) => {
        generate(item.children, router);
      });
      next({ ...to, replace: true });
    } else if (
      toPath.startsWith("/redirect") ||
      toPath.startsWith("/external-view") ||
      toPath === "/" ||
      Boolean(router.getRoutes().filter((item) => toPath === item.path).length)
    ) {
      next();
    } else {
      next({ path: "/" });
    }
  });
};
