import { createRouter, createWebHistory } from 'vue-router'
import Layout from '@/themes'
import { hasAnyActiveRolePermission } from '@/core/utils/activeRolePermission'
import { getRouteRequiredPermissions } from '@/core/utils/routePermission'
import { authPublicRoutes, resolvePostAuthRoute } from '@/modules/auth'
import { membershipApplicationPublicRoutes, membershipApplicationLayoutRoutes } from '@/modules/membership-application'
import { profileLayoutRoutes, profilePublicRoutes } from '@/modules/profile'
import { pinia } from '@/pinia'
import { useAuthStore } from '@/stores/auth'
import { userLayoutRoutes } from '@/modules/user'
import { roleLayoutRoutes } from '@/modules/role'
import { activityLayoutRoutes } from '@/modules/activity'
import { dashboardLayoutRoutes } from '@/modules/dashboard'
import { externalSystemLayoutRoutes } from '@/modules/external-system'
import { activityLogLayoutRoutes } from '@/modules/activity-log'
import { feedbackPublicRoutes, feedbackLayoutRoutes } from '@/modules/feedback'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      // Main Layout
      path: '/',
      component: Layout,
      children: [
        ...dashboardLayoutRoutes,
        ...profileLayoutRoutes,
        ...userLayoutRoutes,
        ...roleLayoutRoutes,
        ...activityLogLayoutRoutes,
        ...activityLayoutRoutes,
        ...externalSystemLayoutRoutes,
        ...membershipApplicationLayoutRoutes,
        ...feedbackLayoutRoutes,
      ],
    },
    ...authPublicRoutes,
    ...membershipApplicationPublicRoutes,
    ...feedbackPublicRoutes,
    ...profilePublicRoutes,
  ],
})

const PUBLIC_ROUTE_NAMES = new Set(['login', 'register', 'membership-application-apply', 'feedback-submit'])

router.beforeEach(async (to) => {
  const authStore = useAuthStore(pinia)
  const routeName = String(to.name ?? '')

  // Hydrate session on public auth entry pages.
  if (PUBLIC_ROUTE_NAMES.has(routeName) && !authStore.isAuthenticated && !authStore.loading) {
    await authStore.fetchSession()
  }

  // Pending-approval page: authenticated pending users only.
  if (routeName === 'account-pending') {
    if (!authStore.isAuthenticated && !authStore.loading) {
      await authStore.fetchSession()
    }

    if (!authStore.isAuthenticated) {
      return { name: 'login' }
    }

    if (!authStore.isAccountPending) {
      return resolvePostAuthRoute(authStore.user)
    }

    return true
  }

  if (
    authStore.isAuthenticated &&
    PUBLIC_ROUTE_NAMES.has(routeName) &&
    routeName !== 'membership-application-apply' &&
    routeName !== 'feedback-submit'
  ) {
    return resolvePostAuthRoute(authStore.user)
  }

  // Public routes (auth pages, membership application, privacy, terms, etc.).
  if (to.meta?.public === true || to.meta?.module === 'auth' || PUBLIC_ROUTE_NAMES.has(routeName)) {
    return true
  }

  // Protected routes: require session.
  if (!authStore.isAuthenticated && !authStore.loading) {
    await authStore.fetchSession()
  }

  if (!authStore.isAuthenticated) {
    return {
      name: 'login',
      query: { redirect: to.fullPath },
    }
  }

  if (authStore.isAccountPending) {
    return { name: 'account-pending' }
  }

  const requiredPermissions = getRouteRequiredPermissions(to)

  if (
    requiredPermissions.length &&
    !hasAnyActiveRolePermission(
      authStore.user,
      authStore.activeRole,
      requiredPermissions,
    )
  ) {
    return { name: 'forbidden' }
  }

  return true
})

export default router
