import { getSelectedProfile, saveLastProfileUsed } from '@/api/profile'
import { useAuthStore } from '@/stores/auth-store'
import { createRouter, createWebHistory, type RouteLocationNormalized } from 'vue-router'

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/login',
      component: () => import('@/pages/LoginPage.vue'),
      meta: { title: 'Login' },
    },
    {
      path: '/',
      component: () => import('@/pages/UserAccountLayout.vue'),
      beforeEnter: onlyAuthenticated,
      children: [
        {
          path: '',
          redirect: '/profiles',
        },
        {
          path: 'me',
          component: () => import('@/pages/MyUserPage.vue'),
          meta: { title: 'My User' },
        },
        {
          path: 'profiles',
          component: () => import('@/pages/ProfilesPage.vue'),
          meta: { title: 'Profiles' },
        },
        {
          path: 'profiles/:profileName',
          children: [
            {
              path: '',
              component: () => import('@/pages/UserHomePage.vue'),
              meta: { title: (to: RouteLocationNormalized) => 'Profile ' + getSelectedProfile(to) },
            },
            {
              path: 'accounts/:id',
              component: () => import('@/pages/AccountPage.vue'),
              meta: { title: 'Account' },
            },
            {
              path: 'accounts/:id/edit',
              component: () => import('@/pages/EditAccountPage.vue'),
              meta: { title: 'Edit Account' },
            },
            {
              path: 'accounts/:accountId/value-records/:valueRecordId',
              component: () => import('@/pages/ValueRecordPage.vue'),
              meta: { title: 'Value Record' },
            },
            {
              path: 'add-account',
              component: () => import('@/pages/EditAccountPage.vue'),
              meta: { title: 'Add Account' },
            },
            {
              path: 'transactions/:id',
              component: () => import('@/pages/TransactionPage.vue'),
              meta: { title: 'Transaction' },
            },
            {
              path: 'transaction-drafts/:id',
              component: () => import('@/pages/TransactionDraftPage.vue'),
              meta: { title: 'Draft' },
            },
            {
              name: 'edit-transaction',
              path: 'transactions/:id/edit',
              component: () => import('@/pages/transaction-editor/EditTransactionPage.vue'),
              meta: { title: 'Edit Transaction' },
            },
            {
              path: 'add-transaction',
              component: () => import('@/pages/transaction-editor/EditTransactionPage.vue'),
              meta: { title: 'Add Transaction' },
            },
            {
              name: 'edit-draft',
              path: 'transaction-drafts/:id/edit',
              component: () => import('@/pages/transaction-editor/EditTransactionPage.vue'),
              meta: { title: 'Edit Draft' },
            },
            {
              path: 'transactions/search',
              component: () => import('@/pages/TransactionSearchPage.vue'),
              meta: { title: 'Search Transactions' },
            },
            {
              path: 'vendors',
              component: () => import('@/pages/VendorsPage.vue'),
              meta: { title: 'Vendors' },
            },
            {
              path: 'vendors/:id',
              component: () => import('@/pages/VendorPage.vue'),
              meta: { title: 'Vendor' },
            },
            {
              path: 'categories',
              component: () => import('@/pages/CategoriesPage.vue'),
              meta: { title: 'Categories' },
            },
            {
              path: 'categories/:id',
              component: () => import('@/pages/CategoryPage.vue'),
              meta: { title: 'Category' },
            },
          ],
        },
      ],
    },
  ],
})

// Adds a webpage title to each route based on the "meta.title" attribute.
router.beforeEach((to) => {
  if (to.meta.title !== undefined && typeof to.meta.title === 'string') {
    document.title = 'Finnow - ' + to.meta.title
  } else if (to.meta.title !== undefined && typeof to.meta.title === 'function') {
    document.title = 'Finnow - ' + to.meta.title(to)
  } else {
    document.title = 'Finnow'
  }
  if (import.meta.env.DEV) {
    document.title = '[DEV]' + document.title
  }
})

// After navigation, save the last used profile to keep track of what the user was last using.
router.afterEach((to) => {
  saveLastProfileUsed(to)
})

/**
 * Guard to ensure a route can only be accessed by authenticated users.
 * @param to The route to guard.
 * @returns True if the user is authenticated, or a redirect to the `/login`
 * page if the user isn't logged in.
 */
function onlyAuthenticated(to: RouteLocationNormalized) {
  const authStore = useAuthStore()
  if (authStore.state) return true
  if (to.path === '/') return '/login'
  return '/login?next=' + encodeURIComponent(to.path)
}

export default router
