import { defu } from 'defu'

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default defineNuxtRouteMiddleware(async (to: any) => {
  const { loggedIn, options, fetchSession, user, signOut } = useAuth()
  const { only, redirectUserTo, redirectGuestTo } = defu(to.meta?.auth, options)
  const localePath = useLocalePath()

  // Allow magic-link redirect/callback pages to run their client-side logic
  // without being intercepted by auth redirects in the browser.
  const skipMagicAuthHandling = to.path.includes('/auth/magic-link-redirect')
    || to.path.includes('/auth/magic-link-callback')
    || to.path.includes('/auth/start-social')
  if (skipMagicAuthHandling) {
    return
  }

  // If guest mode, redirect if authenticated
  if (only === 'guest' && loggedIn.value) {
    // Avoid infinite redirect
    if (to.path === localePath(redirectUserTo)) {
      return
    }
    return navigateTo(localePath(redirectUserTo))
  }

  // Fetch session on client navigations only; SSR hydration happens in server plugin
  if (import.meta.client) {
    await fetchSession()
  }

  // If banned, force sign-out and redirect
  const u = user.value as unknown as { banned?: boolean, bannedUntil?: string | Date }
  if (loggedIn.value && u?.banned) {
    // Optional: check bannedUntil not elapsed
    try {
      const until = u.bannedUntil ? new Date(u.bannedUntil) : null
      const active = !until || until > new Date()
      if (active) {
        await signOut({})
        return navigateTo(localePath('/auth'))
      }
    } catch {
      await signOut({})
      return navigateTo(localePath('/auth'))
    }
  }

  if (loggedIn.value && to.path.startsWith(localePath('/auth'))) {
    return navigateTo(localePath('/dashboard'))
  }

  // If not authenticated and trying to access dashboard, then redirect to home
  if (!loggedIn.value && to.path.startsWith(localePath('/dashboard'))) {
    // Avoid infinite redirect
    if (to.path === localePath(redirectGuestTo)) {
      return
    }
    return navigateTo(localePath(redirectGuestTo))
  }
})
