import { PermissionState } from '@/types/store/permission';
import { RouteRecordRaw } from 'vue-router';
import { defineStore } from 'pinia';
import { constantRoutes, asyncRoutes } from '@/router';
import { localStorage } from '@/utils/storage';

const modules = import.meta.glob('../../views/**/**.vue');
export const Layout = () => import('@/layout/index.vue');

const hasPermission = (roles: string[], route: RouteRecordRaw) => {
  if (route.meta && route.meta.roles) {
    if (roles.includes('ROOT')) {
      return true;
    }
    return roles.some((role) => {
      if (route.meta?.roles !== undefined) {
        return (route.meta.roles as string[]).includes(role);
      }
    });
  }
  return false;
};

export const filterAsyncRoutes = (
  routes: RouteRecordRaw[],
  roles: string[],
  userPermsIds: number[]
) => {
  const res: RouteRecordRaw[] = [];
  routes.forEach((route) => {
    const tmp = { ...route } as any;
    if (userPermsIds.includes(tmp.id)) {
      if (hasPermission(roles, tmp)) {
        if (tmp.component == 'Layout') {
          tmp.component = Layout;
        } else {
          const component = modules[`../../views/${tmp.component}.vue`] as any;
          if (component) {
            tmp.component = modules[`../../views/${tmp.component}.vue`];
          } else {
            tmp.component = modules[`../../views/error-page/404.vue`];
          }
        }
        res.push(tmp);
  
        if (tmp.children) {
          tmp.children = filterAsyncRoutes(tmp.children, roles, userPermsIds);
        }
      }
    }
  });
  return res;
};

const usePermissionStore = defineStore({
  id: 'permission',
  state: (): PermissionState => ({
    routes: [],
    addRoutes: [],
  }),
  actions: {
    setRoutes(routes: RouteRecordRaw[]) {
      this.addRoutes = routes;
      this.routes = constantRoutes.concat(routes);
    },
    generateRoutes() {
      let userPermsIds = [0] as number[];
      let userPerms = localStorage.get("leftSidebarList");
      userPerms.forEach((perm: any) => {
        if (perm.subMenu.length > 0) {
          userPermsIds.push(perm.id)
          perm.subMenu.forEach((subPerm: any) => {
            userPermsIds.push(subPerm.id)
          })
        }
      })
      const accessedRoutes = filterAsyncRoutes(asyncRoutes, ["ROOT"], userPermsIds);
      return new Promise((resolve, reject) => {
        this.setRoutes(accessedRoutes);
        resolve(accessedRoutes);
      });
    },
  },
});

export default usePermissionStore;
