import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router'
import { routes } from '@/plugins/routesLayout'
import { fetchCurrentUser, hasRole } from '@/services/authSession'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: routes.filter((x) => x.meta !== undefined).map((x) => x.meta) as RouteRecordRaw[],
})

router.beforeEach(async (to) => {
  const requiresAuth = to.meta.requiresAuth === true
  const guestOnly = to.meta.guestOnly === true
  const isPasswordChangeRoute = to.name === 'ChangePassword'
  const requiredRoles = Array.isArray(to.meta.requiredRoles)
    ? to.meta.requiredRoles.filter((role): role is string => typeof role === 'string')
    : []

  let currentUser = null

  try {
    currentUser = await fetchCurrentUser()
  } catch {
    if (requiresAuth || requiredRoles.length > 0 || isPasswordChangeRoute) {
      const query = to.fullPath !== '/' ? { redirect: to.fullPath } : {}

      return {
        name: 'Login',
        query,
        replace: true,
      }
    }

    return true
  }

  const isAuthenticated = currentUser !== null

  if (currentUser && currentUser.mustChangePassword && !isPasswordChangeRoute) {
    return {
      name: 'ChangePassword',
      replace: true,
    }
  }

  if (requiresAuth && !isAuthenticated) {
    const query = to.fullPath !== '/' ? { redirect: to.fullPath } : {}

    return {
      name: 'Login',
      query,
      replace: true,
    }
  }

  if (requiredRoles.length > 0 && !requiredRoles.every((role) => hasRole(currentUser, role))) {
    return {
      name: 'Forbidden',
      replace: true,
    }
  }

  if (guestOnly && isAuthenticated) {
    return {
      name: 'Dashboard',
      replace: true,
    }
  }

  return true
})

export default router
