import { useUserStore } from "@/store/UserStore";
import { createRouter, createWebHistory } from "vue-router";
import { api } from "../helpers/api";
import { useApplicationStore } from "../store/ApplicationStore";
import { useProgressStore } from "../store/ProgressStore";

export const routes = [
    {
        path: "/",
        name: "home",
        meta: {
            title: "Home",
        },
        component: () => import("@/views/Home.vue"),
    },
    {
        path: "/verify-email",
        name: "verify-email",
        meta: {
            title: "Verify Email",
        },
        component: () => import("@/views/EmailVerify.vue"),
    },
    {
        path: "/resend-verify-email",
        name: "resend-verify-email",
        meta: {
            title: "Resend Verification Email",
        },
        component: () => import("@/views/ResendEmailVerify.vue"),
    },
    {
        path: "/reset-password",
        name: "reset-password",
        meta: {
            title: "Reset Password",
        },
        component: () => import("@/views/ResetPassword.vue"),
    },
    {
        path: "/privacy",
        name: "privacy",
        meta: {
            title: "Privacy Policy",
        },
        component: () => import("@/views/Privacy.vue"),
    },
    {
        path: "/rules",
        name: "rules",
        meta: {
            title: "Rules",
        },
        component: () => import("@/views/Rules.vue"),
    },
    {
        path: "/unsubscribe",
        name: "unsubscribe",
        meta: {
            title: "Unsubscribe",
        },
        component: () => import("@/views/Unsubscribe.vue"),
    },
    {
        path: "/terms",
        name: "terms",
        meta: {
            title: "Terms and Conditions",
        },
        component: () => import("@/views/Terms.vue"),
    },
    {
        path: "/minecraft",
        name: "minecraft",
        meta: {
            title: "Minecraft",
        },
        component: () => import("@/views/Minecraft.vue"),
    },
    {
        path: "/workshops",
        children: [
            {
                path: "",
                name: "event-list",
                meta: {
                    title: "Workshops",
                },
                component: () => import("@/views/EventList.vue"),
            },
            {
                path: ":id",
                name: "event-view",
                component: () => import("@/views/EventView.vue"),
            },
        ],
    },
    {
        path: "/login",
        name: "login",
        meta: {
            title: "Login",
            middleware: "guest",
        },
        component: () => import("@/views/Login.vue"),
    },
    {
        path: "/logout",
        name: "logout",
        meta: {
            title: "Logout",
        },
        component: () => import("@/views/Logout.vue"),
    },
    {
        path: "/contact",
        name: "contact",
        meta: {
            title: "Contact",
        },
        component: () => import("@/views/Contact.vue"),
    },
    {
        path: "/register",
        name: "register",
        meta: {
            title: "Register",
        },
        component: () => import("@/views/Register.vue"),
    },
    {
        path: "/news",
        children: [
            {
                path: "",
                name: "post-list",
                meta: {
                    title: "News",
                },
                component: () => import("@/views/PostList.vue"),
            },
            {
                path: ":slug",
                name: "post-view",
                component: () => import("@/views/PostView.vue"),
            },
        ],
    },
    {
        path: "/dashboard",
        children: [
            {
                path: "",
                name: "dashboard",
                meta: {
                    title: "Dashboard",
                    middleware: "authenticated",
                },
                component: () => import("@/views/dashboard/Dashboard.vue"),
            },
            {
                path: "posts",
                children: [
                    {
                        path: "",
                        name: "dashboard-post-list",
                        meta: {
                            title: "Posts",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/PostList.vue"),
                    },
                    {
                        path: "create",
                        name: "dashboard-post-create",
                        meta: {
                            title: "Create Post",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/PostEdit.vue"),
                    },
                    {
                        path: ":id",
                        name: "dashboard-post-edit",
                        meta: {
                            title: "Edit Post",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/PostEdit.vue"),
                    },
                ],
            },
            {
                path: "events",
                children: [
                    {
                        path: "",
                        name: "dashboard-event-list",
                        meta: {
                            title: "Events",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/EventList.vue"),
                    },
                    {
                        path: "create",
                        name: "dashboard-event-create",
                        meta: {
                            title: "Create Event",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/EventEdit.vue"),
                    },
                    {
                        path: ":id",
                        name: "dashboard-event-edit",
                        meta: {
                            title: "Event Post",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/EventEdit.vue"),
                    },
                ],
            },
            {
                path: "details",
                name: "dashboard-account-details",
                meta: {
                    title: "Account Details",
                    middleware: "authenticated",
                },
                component: () => import("@/views/dashboard/UserEdit.vue"),
            },
            {
                path: "users",
                children: [
                    {
                        path: "",
                        name: "dashboard-user-list",
                        meta: {
                            title: "Users",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/UserList.vue"),
                    },
                    {
                        path: ":id",
                        name: "dashboard-user-edit",
                        meta: {
                            title: "Edit User",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/UserEdit.vue"),
                    },
                ],
            },
            {
                path: "media",
                children: [
                    {
                        path: "",
                        name: "dashboard-media-list",
                        meta: {
                            title: "Media",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/MediaList.vue"),
                    },
                    {
                        path: "upload",
                        name: "dashboard-media-upload",
                        meta: {
                            title: "Upload Media",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/MediaEdit.vue"),
                    },
                    {
                        path: "edit/:id",
                        name: "dashboard-media-edit",
                        meta: {
                            title: "Edit Media",
                            middleware: "authenticated",
                        },
                        component: () =>
                            import("@/views/dashboard/MediaEdit.vue"),
                    },
                ],
            },
            {
                path: "discord-bot-logs",
                name: "dashboard-discord-bot-logs",
                meta: {
                    title: "Discord Bot Logs",
                    middleware: "authenticated",
                },
                component: () => import("@/views/dashboard/DiscordBotLogs.vue"),
            },
        ],
    },
    {
        path: "/forgot-username",
        name: "forgot-username",
        meta: {
            title: "Forgot Username",
        },
        component: () => import("@/views/ForgotUsername.vue"),
    },
    {
        path: "/forgot-password",
        name: "forgot-password",
        meta: {
            title: "Forgot Password",
        },
        component: () => import("@/views/ForgotPassword.vue"),
    },
    {
        path: "/error/internal",
        name: "error-internal",
        meta: {
            title: "Server error",
            hideInEditor: true,
        },
        component: () => import("@/components/errors/Internal.vue"),
    },
    {
        path: "/error/forbidden",
        name: "forbidden",
        meta: {
            title: "Forbidden",
            hideInEditor: true,
        },
        component: () => import("@/components/errors/Forbidden.vue"),
    },
    {
        path: "/:catchAll(.*)",
        name: "not-found",
        meta: {
            title: "Page not found",
            hideInEditor: true,
        },
        component: () => import("@/components/errors/NotFound.vue"),
    },
];

const router = createRouter({
    history: createWebHistory(),
    routes,
    scrollBehavior(to, from, savedPosition) {
        // always scroll to top
        return { top: 0 };
    },
});

// export let activeRoutes = [];

router.beforeEach(async (to, from, next) => {
    const userStore = useUserStore();
    const applicationStore = useApplicationStore();
    const progressStore = useProgressStore();

    progressStore.start();

    applicationStore.clearDynamicTitle();

    // Check Token
    if (userStore.id) {
        let redirect = false;

        try {
            let res = await api.get("/me");
            userStore.setUserDetails(res.json.user);
        } catch (err) {
            if (err.status == 401) {
                userStore.clearUser();
                redirect = true;
            }
        }

        if (
            redirect &&
            to.path.startsWith("/error/") === false &&
            to.path.startsWith("/login") === false
        ) {
            next({ name: "login", query: { redirect: to.fullPath } });
            return;
        }
    }

    // Document Title
    const nearestWithTitle = to.matched
        .slice()
        .reverse()
        .find((r) => r.meta && r.meta.title);
    const previousNearestWithMeta = from.matched
        .slice()
        .reverse()
        .find((r) => r.meta && r.meta.metaTags);

    let title = "";
    if (nearestWithTitle) {
        title = nearestWithTitle.meta.title;
    } else if (previousNearestWithMeta) {
        title = previousNearestWithMeta.meta.title;
    }

    if (title != "") {
        document.title = "STEMMechanics | " + title;
    }

    // Meta tags
    const nearestWithMeta = to.matched
        .slice()
        .reverse()
        .find((r) => r.meta && r.meta.metaTags);
    Array.from(document.querySelectorAll("[data-vue-router-controlled]")).map(
        (el) => el.parentNode.removeChild(el)
    );
    if (nearestWithMeta) {
        nearestWithMeta.meta.metaTags
            .map((tagDef) => {
                const tag = document.createElement("meta");

                Object.keys(tagDef).forEach((key) => {
                    tag.setAttribute(key, tagDef[key]);
                });

                tag.setAttribute("data-vue-router-controlled", "");

                return tag;
            })
            .forEach((tag) => document.head.appendChild(tag));
    }

    if (to.meta.middleware == "authenticated" && !userStore.id) {
        progressStore.finish();
        next({ name: "login", query: { redirect: to.fullPath } });
    } else {
        next();
    }
});

router.afterEach((to, from) => {
    const progressStore = useProgressStore();
    progressStore.finish();
});

export default router;
