import { createRouter, createWebHistory } from 'vue-router'
import { loadSiteStatus } from './lib/siteStatus'
import { useAuthStore } from './stores/auth'
import { useAwardsStore } from './stores/awards'
import { routes } from './router/routes'

const DEMO_GATE_FALLBACK_ENABLED = import.meta.env.VITE_DEMO_GATE_ENABLED !== 'false'
const adminRoutePermissions: Record<string, string> = {
  'admin-dashboard': 'dashboard',
  'admin-years': 'years',
  'admin-nominations': 'nominations',
  'admin-categories': 'categories',
  'admin-candidates': 'candidates',
  'admin-clips': 'clips',
  'admin-risk': 'risk',
  'admin-users-logs': 'audit',
  'admin-team': 'team',
  'admin-analytics': 'analytics',
  'admin-voting': 'voting',
  'admin-winners': 'winners',
  'admin-content': 'content',
  'admin-settings': 'settings',
  'admin-settings-access': 'settings',
  'admin-settings-workflows': 'settings',
  'admin-tracking-rules': 'settings',
}

function hasAdminPermission(permissionKeys: string[] = [], permissionKey: string) {
  if (permissionKeys.includes(permissionKey)) {
    return true
  }

  if (permissionKey === 'voting') {
    return permissionKeys.includes('analytics') || permissionKeys.includes('winners')
  }

  return false
}

function firstAllowedAdminRoute(permissionKeys: string[] = []) {
  const preferredRoutes = [
    'admin-dashboard',
    'admin-nominations',
    'admin-clips',
    'admin-content',
    'admin-analytics',
    'admin-settings',
    'admin-team',
  ]

  return preferredRoutes.find((routeName) => hasAdminPermission(permissionKeys, adminRoutePermissions[routeName]))
    ?? Object.entries(adminRoutePermissions).find(([, permission]) => hasAdminPermission(permissionKeys, permission))?.[0]
    ?? 'home'
}

const router = createRouter({
  history: createWebHistory(),
  scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
      return savedPosition
    }

    if (to.path.startsWith('/admin') && from.path.startsWith('/admin')) {
      return false
    }

    return { top: 0 }
  },
  routes,
})

router.beforeEach(async (to) => {
  const authStore = useAuthStore()

  if (!authStore.hydrated) {
    await authStore.hydrate()
  }

  const isLoginRoute = to.name === 'login'
  const isTwitchCallbackRoute = to.name === 'twitch-auth-callback'
  const isMaintenanceRoute = to.name === 'maintenance'
  const isAdminRoute = to.path.startsWith('/admin')
  const isMaintenancePreview = isMaintenanceRoute && to.query.preview === 'true'
  const siteStatus = await loadSiteStatus()
  const demoGateEnabled = siteStatus
    ? siteStatus.demoLoginEnabled
    : DEMO_GATE_FALLBACK_ENABLED

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

  if (siteStatus?.maintenanceModeEnabled && !isMaintenanceRoute && !isLoginRoute && !isTwitchCallbackRoute && !isAdminRoute) {
    return { name: 'maintenance', query: { from: to.fullPath } }
  }

  if (isMaintenanceRoute && !isMaintenancePreview && siteStatus && !siteStatus.maintenanceModeEnabled) {
    return { name: 'home' }
  }

  if (demoGateEnabled && !isLoginRoute && !isTwitchCallbackRoute && !isMaintenanceRoute && !authStore.isLoggedIn) {
    return { name: 'login', query: { redirect: to.fullPath } }
  }

  if (authStore.session?.mustChangePassword && !isLoginRoute && !isTwitchCallbackRoute) {
    return { name: 'login', query: { redirect: to.fullPath, change: 'password' } }
  }

  if (demoGateEnabled && isLoginRoute && authStore.isLoggedIn && !authStore.session?.mustChangePassword) {
    const redirect = Array.isArray(to.query.redirect)
      ? to.query.redirect[0]
      : to.query.redirect

    return typeof redirect === 'string' && redirect.startsWith('/') && !redirect.startsWith('/login')
      ? redirect
      : { name: 'home' }
  }

  if (to.meta.requiresAuth && !authStore.isLoggedIn) {
    return { name: 'login', query: { redirect: to.fullPath } }
  }

  if (to.meta.requiresAdmin && !authStore.isAdmin) {
    return { name: 'login', query: { redirect: to.fullPath } }
  }

  if (to.path.startsWith('/admin') && authStore.session) {
    const routeName = String(to.name ?? '')
    const neededPermission = adminRoutePermissions[routeName]
    if (neededPermission && !hasAdminPermission(authStore.session.permissionKeys, neededPermission)) {
      const fallback = firstAllowedAdminRoute(authStore.session.permissionKeys)
      return fallback === 'home' ? { name: 'home' } : { name: fallback }
    }
  }

  // Phasen-Gate: eine Aktion ist nur in ihrem aktiven Zeitfenster erreichbar.
  if (typeof to.meta.phase === 'string') {
    const awardsStore = useAwardsStore()
    const phase = awardsStore.overview.timeline.find((entry) => entry.key === to.meta.phase)
    if (phase?.state !== 'active') {
      return { name: 'home' }
    }
  }

  return true
})

export default router
