import { createRouter, createWebHistory } from 'vue-router'
import { nextTick } from 'vue'
import { useAppStore } from '../stores/app'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      component: () => import('../views/OnboardingWrapper.vue'),
      meta: { public: true },
      children: [
        {
          path: '',
          component: () => import('../views/RootRedirect.vue'),
        },
        {
          path: 'login',
          name: 'login',
          component: () => import('../views/Login.vue'),
        },
        {
          path: 'onboarding/intro',
          name: 'onboarding-intro',
          component: () => import('../views/OnboardingIntro.vue'),
        },
        {
          path: 'onboarding/options',
          name: 'onboarding-options',
          component: () => import('../views/OnboardingOptions.vue'),
        },
        {
          path: 'onboarding/path',
          name: 'onboarding-path',
          component: () => import('../views/OnboardingPath.vue'),
        },
        {
          path: 'onboarding/did',
          name: 'onboarding-did',
          component: () => import('../views/OnboardingDid.vue'),
        },
        {
          path: 'onboarding/backup',
          name: 'onboarding-backup',
          component: () => import('../views/OnboardingBackup.vue'),
        },
        {
          path: 'onboarding/verify',
          name: 'onboarding-verify',
          component: () => import('../views/OnboardingVerify.vue'),
        },
        {
          path: 'onboarding/done',
          name: 'onboarding-done',
          component: () => import('../views/OnboardingDone.vue'),
        },
      ],
    },
    {
      path: '/dashboard',
      component: () => import('../views/Dashboard.vue'),
      children: [
        {
          path: '',
          name: 'home',
          component: () => import('../views/Home.vue'),
        },
        {
          path: 'apps',
          name: 'apps',
          component: () => import('../views/Apps.vue'),
        },
        {
          path: 'apps/:id',
          name: 'app-details',
          component: () => import('../views/AppDetails.vue'),
        },
        {
          path: 'marketplace',
          name: 'marketplace',
          component: () => import('../views/Marketplace.vue'),
        },
        {
          path: 'marketplace/:id',
          name: 'marketplace-app-detail',
          component: () => import('../views/MarketplaceAppDetails.vue'),
        },
        {
          path: 'cloud',
          name: 'cloud',
          component: () => import('../views/Cloud.vue'),
        },
        {
          path: 'cloud/:folderId',
          name: 'cloud-folder',
          component: () => import('../views/CloudFolder.vue'),
        },
        {
          path: 'server',
          name: 'server',
          component: () => import('../views/Server.vue'),
        },
        {
          path: 'web5',
          name: 'web5',
          component: () => import('../views/Web5.vue'),
        },
        {
          path: 'settings',
          name: 'settings',
          component: () => import('../views/Settings.vue'),
        },
        {
          path: 'goals/:goalId',
          name: 'goal-detail',
          component: () => import('../views/GoalDetail.vue'),
        },
        {
          path: 'chat',
          name: 'chat',
          component: () => import('../views/Chat.vue'),
        },
        // Containers removed: My Apps serves the same purpose. Redirect old links.
        {
          path: 'containers',
          redirect: () => ({ path: '/dashboard/apps' }),
        },
        {
          path: 'containers/:id',
          redirect: (to) => ({ path: `/dashboard/apps/${to.params.id}` }),
        },
      ],
    },
  ],
})

// Session check with timeout - avoids endless spinner on mobile/slow networks
const SESSION_CHECK_TIMEOUT_MS = 8000

async function checkSessionWithTimeout(store: ReturnType<typeof useAppStore>): Promise<boolean> {
  try {
    return await Promise.race([
      store.checkSession(),
      new Promise<boolean>((resolve) =>
        setTimeout(() => resolve(false), SESSION_CHECK_TIMEOUT_MS)
      ),
    ])
  } catch {
    return false
  }
}

/**
 * Navigation Guard
 * Handles authentication and onboarding flow routing
 */
router.beforeEach(async (to, _from, next) => {
  const store = useAppStore()
  const isPublic = to.meta.public

  // Allow all public routes (login, onboarding) without auth check
  if (isPublic) {
    // If authenticated and visiting /login: show login immediately, validate in background.
    // This prevents endless spinner on mobile when checkSession hangs (slow/unreachable network).
    if (to.path === '/login' && store.isAuthenticated) {
      if (store.needsSessionValidation()) {
        next()
        checkSessionWithTimeout(store).then((valid) => {
          if (valid) {
            router.replace({ name: 'home' }).catch(() => {})
          }
        })
        return
      }
      next({ name: 'home' })
      return
    }
    next()
    return
  }

  // Protected routes: validate session if stale auth from localStorage
  if (store.needsSessionValidation()) {
    // localStorage says we're authed — proceed immediately, revalidate in background.
    // No timeout wrapper here: a slow server shouldn't bounce the user to login.
    next()
    store.checkSession().then((valid) => {
      if (!valid) {
        router.replace('/login').catch(() => {})
      }
    })
    return
  }

  // Not authenticated at all (with timeout to avoid endless spinner on mobile)
  if (!store.isAuthenticated) {
    const hasSession = await checkSessionWithTimeout(store)
    if (hasSession) {
      next()
      return
    }
    next('/login')
    return
  }

  // Validated and authenticated - ensure WebSocket is connected
  if (!store.isConnected && !store.isReconnecting) {
    store.connectWebSocket().catch((err) => {
      console.warn('[Router] WebSocket connection failed:', err)
    })
  }

  next()
})

// Focus Home nav item for gamepad when landing on dashboard home (e.g. after login)
router.afterEach((to) => {
  if (to.path === '/dashboard' || to.path === '/dashboard/') {
    nextTick(() => {
      setTimeout(() => {
        const homeLink = document.querySelector<HTMLAnchorElement>(
          '[data-controller-zone="sidebar"] a[href="/dashboard"], [data-controller-zone="sidebar"] a[href="/dashboard/"]'
        )
        if (homeLink) homeLink.focus()
      }, 150)
    })
  }
})

export default router

