import AppLayout from "../layout/AppLayout.vue";
import AuthLayout from "../layout/AuthLayout.vue";
import { hydrateUser, userRef } from "../composables/useAuth";

import { createRouter, createWebHistory } from "vue-router";

export const coreRoutes = [
  {
    path: "/auth",
    component: AuthLayout,
    children: [
      {
        path: "login",
        name: "login",
        meta: { guest: true },
        component: () => import("../views/auth/LoginView.vue"),
      },
      {
        path: "oops",
        name: "auth-oops",
        component: () => import("../views/pages/Oops.vue"),
      },
      {
        path: "access",
        name: "auth-access",
        component: () => import("../views/pages/AccessDenied.vue"),
      },
    ],
  },
  {
    path: "/pages/notfound",
    component: AuthLayout,
    children: [
      {
        path: "",
        name: "pages-not-found",
        component: () => import("../views/pages/NotFound.vue"),
      },
    ],
  },
  {
    path: "/",
    component: AppLayout,
    meta: { requiresAuth: true },
    children: [
      {
        path: "",
        redirect: "/dashboard",
      },
      {
        path: "dashboard",
        name: "dashboard",
        meta: {
          breadcrumb: ["Dashboard"],
          title: "Dashboard",
        },
        component: () => import("../views/dashboard/EcommerceView.vue"),
      },
      {
        path: "settings",
        name: "settings",
        meta: {
          breadcrumb: ["Settings"],
          title: "Settings",
        },
        component: () => import("../views/settings/SettingsRedirectView.vue"),
      },
      {
        path: "settings/organization",
        name: "settings-organization",
        meta: {
          breadcrumb: ["Settings", "Organization"],
          title: "Organization",
          permission: "settings.organization.view",
        },
        component: () => import("../views/organization/OrganizationProfileView.vue"),
      },
      {
        path: "settings/users",
        name: "settings-users",
        meta: {
          breadcrumb: ["Settings", "Users"],
          title: "Users",
          permission: "users.view",
        },
        component: () => import("../views/settings/UsersView.vue"),
      },
      {
        path: "settings/roles",
        name: "settings-roles",
        meta: {
          breadcrumb: ["Settings", "Roles"],
          title: "Roles",
          permission: "roles.view",
        },
        component: () => import("../views/settings/RolesManagementView.vue"),
      },
      {
        path: "settings/activity-log",
        name: "settings-activity-log",
        meta: {
          breadcrumb: ["Settings", "Activity log"],
          title: "Activity log",
          permission: "activitylog.view",
        },
        component: () => import("../views/settings/ActivityLogView.vue"),
      },
    ],
  },
  {
    path: "/:pathMatch(.*)*",
    name: "fallback-not-found",
    component: () => import("../views/pages/NotFound.vue"),
  },
];

/**
 * Create the SPA router. Pass an optional callback to register customer routes
 * (e.g. router.addRoute) before the app mounts.
 *
 * @param {(router: import('vue-router').Router) => void} [extendRouter]
 */
export function createCoreRouter(extendRouter) {
  let bootstrapAuth = false;

  const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: coreRoutes,
  });

  router.beforeEach(async (to, from, next) => {
    if (!bootstrapAuth) {
      await hydrateUser();
      bootstrapAuth = true;
    }

    const isAuthed = Boolean(userRef.value);

    if (to.meta.requiresAuth && !isAuthed) {
      next({
        name: "login",
        query: { redirect: to.fullPath },
        replace: true,
      });

      return;
    }

    if (to.meta.guest && isAuthed) {
      next({ path: "/dashboard", replace: true });

      return;
    }

    const required = to.matched
      .map((r) => r.meta?.permission)
      .filter((p) => typeof p === "string");
    if (required.length && isAuthed && userRef.value) {
      const perms = userRef.value.permissions ?? [];
      const allowed = required.every((p) => perms.includes(p));
      if (!allowed) {
        next({ name: "auth-access", replace: true });

        return;
      }
    }

    next();
  });

  if (typeof extendRouter === "function") {
    extendRouter(router);
  }

  return router;
}
