import { tempErrorRouteName, usePageStore } from '@/stores/page';
import { useUserStore } from '@/stores/user';
import type { MaybeArray } from '@/utils/types';
import { PageErrorType, type PageErrorReason } from '@/views/ErrorPage.vue';
import {
  createRouter,
  createWebHistory,
  type RouteLocationNormalizedGeneric,
  type RouteRecordRaw,
} from 'vue-router';
import { ClubPermissionId, UserPermissionId } from './permissions';
import { ElMessage } from 'element-plus';
export type RoutePermissionRelation = 'AND' | 'OR';
export type RoutePermission<T extends number> =
  | MaybeArray<T>
  | {
      id: MaybeArray<T>;
      /** @default 'AND' */
      relation?: RoutePermissionRelation;
    };
declare module 'vue-router' {
  interface RouteMeta {
    routeId?: number;
    shouldLogin?: boolean;
    permission?:
      | {
          user?: RoutePermission<UserPermissionId>;
          club?: RoutePermission<ClubPermissionId>;
        }
      | ((userStore: ReturnType<typeof useUserStore>) => boolean);
    breadcrumb?: string;
  }
}
function validateParamId(to: RouteLocationNormalizedGeneric, from: RouteLocationNormalizedGeneric) {
  const id = Number(to.params.id);
  if (isNaN(id) || id < 1) {
    ElMessage.error('参数错误');
    return from;
  }
}
const routes: RouteRecordRaw[] = [
  {
    path: '/',
    name: 'Home',
    component: () => import('@/views/MainPage.vue'),
    meta: {
      breadcrumb: '首页',
    },
  },
  {
    path: '/user/:id',
    name: 'User',
    component: () => import('@/views/user/UserPage.vue'),
    redirect: ({ params: { id } }) => ({
      name: useUserStore().isSelf(id as string) ? 'UserEdit' : 'UserPost',
    }),
    children: [
      {
        path: 'post',
        name: 'UserPost',
        component: () => import('@/views/user/UserPostPage.vue'),
      },
      {
        path: 'edit',
        name: 'UserEdit',
        component: () => import('@/views/user/UserEditPage.vue'),
        meta: {
          shouldLogin: true,
        },
      },
    ],
  },
  {
    path: '/club',
    name: 'ClubList',
    component: () => import('@/views/club/ClubListPage.vue'),
  },
  {
    path: '/club/press',
    name: 'ClubPressList',
    component: () => import('@/views/club/ClubPressListPage.vue'),
  },
  {
    path: '/club/:id',
    name: 'ClubInfo',
    component: () => import('@/views/club/ClubInfoPage.vue'),
    meta: {
      permission: { club: ClubPermissionId.CLUB_PAGE },
    },
  },
  {
    path: '/2048',
    name: '2048',
    component: () => import('@/views/Game2048Page.vue'),
  },
  {
    path: '/gobang',
    name: 'GobangList',
    component: () => import('@/views/GobangListPage.vue'),
    meta: {
      shouldLogin: true,
    },
  },
  {
    path: '/gobang/single',
    name: 'GobangPlaySingle',
    component: () => import('@/views/GobangPlayPage.vue'),
    meta: {
      shouldLogin: true,
    },
  },
  {
    path: '/gobang/:id',
    name: 'GobangPlayMulti',
    component: () => import('@/views/GobangPlayPage.vue'),
    meta: {
      shouldLogin: true,
    },
  },
  {
    path: '/manage',
    name: 'Manage',
    component: () => import('@/views/manage/ManagePage.vue'),
    children: [
      {
        path: '',
        name: 'ManageMain',
        component: () => import('@/views/manage/ManageMainPage.vue'),
      },
      {
        path: 'user',
        name: 'ManageUser',
        component: () => import('@/views/manage/ManageUserPage.vue'),
        meta: {
          permission: { user: UserPermissionId.MANAGE_USER },
          breadcrumb: '用户管理',
        },
      },
      {
        path: 'club',
        children: [
          {
            path: '',
            name: 'ManageClub',
            component: () => import('@/views/manage/ManageClubPage.vue'),
          },
          {
            path: ':id/edit',
            name: 'ManageClubEdit',
            component: () => import('@/views/manage/ManageClubEditPage.vue'),
            beforeEnter: validateParamId,
            props: (to) => ({ id: Number(to.params.id) }),
            meta: {
              breadcrumb: '编辑社团',
            },
          },
          {
            path: ':id/member',
            name: 'ManageClubMember',
            component: () => import('@/views/manage/ManageClubMemberPage.vue'),
            beforeEnter: validateParamId,
            props: (to) => ({ id: Number(to.params.id) }),
            meta: {
              breadcrumb: '社团成员',
            },
          },
        ],
        meta: {
          permission: { user: UserPermissionId.MANAGE_PAGE },
          breadcrumb: '社团管理',
        },
      },
    ],
    redirect: { name: 'ManageMain' },
    meta: {
      breadcrumb: '系统首页',
      permission: {
        user: {
          id: [UserPermissionId.MANAGE_PAGE, UserPermissionId.MANAGE_USER],
          relation: 'OR',
        },
      },
    },
  },
  {
    path: '/:path(.*)*',
    name: 'NotFound',
    component: () => import('@/views/ErrorPage.vue'),
    props: {
      type: PageErrorType.NOT_FOUND,
    } satisfies PageErrorReason,
  },
];
const router = createRouter({
  history: createWebHistory(),
  routes: routes,
});

router.beforeEach(async (to) => {
  if (to.name === tempErrorRouteName) {
    return true;
  }
  const userStore = useUserStore();
  const pageStore = usePageStore();
  pageStore.setNewRouteId(to);
  if (!userStore.userInfo) {
    const succeed = await userStore.updateSelfUserInfo();
    if (!succeed) {
      return pageStore.createTempErrorRoute(
        {
          type: PageErrorType.NETWORK_ERROR,
        },
        to,
      );
    }
  }

  const type = userStore.isRouteAccessible(to.fullPath);
  if (type !== true) {
    return pageStore.createTempErrorRoute({ type }, to);
  }
  return true;
});
router.afterEach((to) => {
  const pageStore = usePageStore();
  pageStore.removeRouteId(to);
  if (router.hasRoute(tempErrorRouteName)) {
    router.removeRoute(tempErrorRouteName);
  }
});
export default router;
