import { createRouter, createWebHashHistory } from "vue-router";
import { ElNotification, ElMessageBox } from "element-plus";
import config from "@/config";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import tool from "@/utils/tool";
import api from "@/api";
import systemRouter from "./systemRouter";
import userRoutes from "@/config/route";
import { beforeEach, afterEach } from "./scrollBehavior";

//系统路由
const routes = systemRouter

//系统特殊路由
const routes_404 = {
    path: "/:pathMatch(.*)*",
    hidden: true,
    component: () => import(/* webpackChunkName: "404" */ "@/layout/other/404"),
}

const routes_empty = {
    path: "/:pathMatch(.*)*",
    hidden: true,
    component: () => import(/* webpackChunkName: "404" */ "@/layout/other/empty"),
}

let routes_404_r = () => { }

const router = createRouter({
    history: createWebHashHistory(),
    routes: routes
})

//设置标题
document.title = config.APP_NAME;

//判断是否已加载过动态/静态路由
let isGetRouter = false;
//FIX 多个API同时401时疯狂弹窗BUG
let MessageBox_401_show = false

router.beforeEach(async (to, from, next) => {
    // 组件iframe 不显示NProgress
    if (to.path !== "/process-form-view") NProgress.start();
    else isGetRouter = true;

    // 动态标题
    document.title = to.meta.title ? `${to.meta.title} - ${config.APP_NAME}` : `${config.APP_NAME}`;

    if (to.path === "/redirect") {
        if (to.query.userId) {
            const { token, user } = await api.auth.oa.getUserToken(to.query);
            if (!tool.cookie.get("TOKEN")) {
                tool.cookie.set("TOKEN", token);
                tool.data.set("USER_INFO", user.user);
            } else tool.data.set("OA_USER_INFO", user.user);

            let applySql = null;
            const { id, projectIds } = user.user;
            if (id && id != 1) {
                applySql = `create_id = ${id}`;
                if (projectIds) applySql += ` or project_id in (${projectIds})`;
            }
            applySql && tool.data.set("APPLY_SQL", applySql);
        }

        next(to.query.path && to.fullPath.replace("/redirect", to.query.path) || (from.fullPath == "/login" && "/" || from.fullPath));
        return false;
    }

    if (to.path === "/process-form-view") {
        if (!tool.cookie.get("TOKEN")) {
            const { token, user } = await api.auth.oa.getUserToken({ userId: 1 });
            tool.session.set("TOKEN", token);
            tool.data.set("USER_INFO", user.user);
        }
        isGetRouter = true;
        next();
        return false;
    }

    if (to.path === "/login") {
        // 删除路由(替换当前layout路由)
        router.addRoute(routes[0]);
        // 删除路由(404)
        routes_404_r();
        isGetRouter = false
        if (tool.cookie.get("TOKEN")) next(from.fullPath);
        else {
            to.redirectedFrom = from;
            next();
        }
        return false;
    }

    if (!tool.cookie.get("TOKEN")) {
        next({ path: "/login" });
        return false;
    }

    // 整页路由处理
    if (to.meta.fullpage) to.matched = [to.matched[to.matched.length - 1]];
    try {
        // 加载动态/静态路由
        if (!isGetRouter) {
            const menus = await api.system.menu.build();
            let apiMenu = menus.filter(m => !(!m.name && m.children[0].component == "Layout"));

            isGetRouter = true;
            if (apiMenu.length == 0) {
                if (!MessageBox_401_show) {
                    MessageBox_401_show = true;
                    ElMessageBox.confirm("当前用户无任何菜单权限，请联系系统管理员", "无权限访问", {
                        type: "error",
                        showClose: false,
                        closeOnPressEscape: false,
                        closeOnClickModal: false,
                        center: true,
                        confirmButtonText: "重新登录",
                        showCancelButton: false,
                        beforeClose: (action, instance, done) => {
                            MessageBox_401_show = false;
                            done();
                        }
                    }).then(() => {
                        tool.cookie.remove("TOKEN");
                        tool.data.remove("USER_INFO");
                        tool.data.remove("OA_USER_INFO");
                        tool.data.remove("APPLY_SQL");
                        location.reload(); // 为了重新实例化vue-router对象 避免bug
                    }).catch(() => { });
                }

                routes_404_r = router.addRoute(routes_empty);
            } else {
                apiMenu = apiMenu.map(item => {
                    // 处理直接创建的菜单路由
                    if (!item.name) {
                        item = {
                            name: item.children[0].meta.title,
                            path: item.iframe ? item.children[0].path : item.path,
                            component: item.children[0].component,
                            iframe: item.iframe,
                            meta: { ...item.children[0].meta },
                            children: undefined
                        }
                    }

                    if (item.children) {
                        item.children.forEach(child => {
                            if (!child.iframe) child.path = item.path + "/" + child.path
                        })
                        item.redirect = item.children[0].path
                    }
                    return item;
                });

                const permission = menus.filter(m => m.permission).map(m => m.permission);
                tool.data.set("PERMISSIONS", [...permission]);
                tool.data.set("MENU", [...userRoutes, ...apiMenu]);
                filterAsyncRouter([...userRoutes, ...apiMenu]);
                routes_404_r = router.addRoute(routes_404);
            }

            if (to.matched.length == 0) router.push(to.fullPath);
        }
    } catch (error) {
        if (tool.cookie.get("TOKEN")) tool.cookie.remove("TOKEN");
    }

    beforeEach(to, from);
    next();
});

router.afterEach((to, from) => {
    afterEach(to, from);
    NProgress.done();
});

router.onError((error) => {
    NProgress.done();
    ElNotification.error({
        title: "路由错误",
        message: error.message
    });

    // const pattern = /Loading chunk (\d)+ failed/g;
    // const isChunkLoadFailed = error.message.match(pattern);
    // const targetPath = router.history.pending.fullPath;
    // if (isChunkLoadFailed) {
    //     router.replace(targetPath);
    // }
});

// 生成路由对象
function filterAsyncRouter(routerMap) {
    routerMap.forEach(item => {
        const route = {
            path: item.path,
            name: item.name,
            meta: item.meta ? item.meta : {},
            redirect: item.redirect || undefined,
            children: item.children && filterAsyncRouter(item.children) || undefined,
            component: loadComponent(item)
        }
        router.addRoute("layout", route);
    })
}

function loadComponent({ component, children }) {
    if (!component || (component == "Layout" && !children)) return () => import(`@/layout/other/empty`);
    return () => import(/* webpackChunkName: "[request]" */ `@/views/${component}`);
}

export default router;