<template>
  <div class="min-h-full">
    <BootScreen :visible="showBootScreen" @ready="onServerReady" />
    <div v-if="!showBootScreen" class="min-h-full flex items-center justify-center">
      <div class="flex flex-col items-center gap-4 opacity-0 root-redirect-fade">
        <svg class="animate-spin h-8 w-8 text-white/60" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
          <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
          <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
        </svg>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { isOnboardingComplete } from '@/composables/useOnboarding'
import BootScreen from '@/components/BootScreen.vue'

const router = useRouter()
const showBootScreen = ref(false)

async function quickHealthCheck(): Promise<boolean> {
  try {
    const ac = new AbortController()
    const t = setTimeout(() => ac.abort(), 2000)
    const res = await fetch('/rpc/v1', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'server.echo', params: { message: 'ping' } }),
      signal: ac.signal,
    })
    clearTimeout(t)
    return res.status !== 502 && res.status !== 503
  } catch {
    return false
  }
}

async function checkOnboarded(): Promise<boolean> {
  try {
    const result = await Promise.race([
      isOnboardingComplete(),
      new Promise<boolean>((resolve) => setTimeout(() => resolve(false), 3000)),
    ])
    return result
  } catch {
    // Backend unreachable — fall back to localStorage only as last resort
    return localStorage.getItem('neode_onboarding_complete') === '1'
  }
}

async function proceedToApp() {
  const devMode = import.meta.env.VITE_DEV_MODE
  if (devMode === 'setup' || devMode === 'existing') {
    router.replace('/login').catch(() => {})
    return
  }

  // Always check backend for authoritative onboarding state
  // (localStorage can be stale from a previous install on the same IP)
  const onboarded = await checkOnboarded()
  router.replace(onboarded ? '/login' : '/onboarding/intro').catch(() => {})
}

function onServerReady() {
  if (import.meta.env.DEV) console.log('[RootRedirect] onServerReady — setting flag and reloading')
  localStorage.removeItem('neode_intro_seen')
  localStorage.removeItem('neode_onboarding_complete')
  sessionStorage.setItem('archipelago_from_boot', '1')
  window.location.href = '/'
}

onMounted(async () => {
  const devMode = import.meta.env.VITE_DEV_MODE

  // Coming back from boot screen — let App.vue's SplashScreen take over
  if (sessionStorage.getItem('archipelago_from_boot') === '1') {
    return
  }

  // Splash already completed this session — go to app
  if (sessionStorage.getItem('archipelago_from_splash') === '1') {
    proceedToApp()
    return
  }

  // Standard dev modes
  if (devMode === 'setup' || devMode === 'existing') {
    proceedToApp()
    return
  }

  // Boot dev mode — always show boot screen (first load only)
  if (devMode === 'boot') {
    showBootScreen.value = true
    return
  }

  // Production: check server health
  const isUp = await quickHealthCheck()

  if (isUp) {
    // Server is up — check if onboarding is complete
    const onboarded = await checkOnboarded()
    if (onboarded) {
      // Returning user, server is up — go straight to login
      proceedToApp()
      return
    }
    // First boot: server is up but onboarding not done yet.
    // Show boot animation anyway — it lets services fully warm up
    // (containers, DID resolver, etc.) before onboarding starts.
  }

  // Server not ready OR first boot — show boot screen
  showBootScreen.value = true
})
</script>

<style scoped>
.root-redirect-fade {
  animation: root-fade-in 0.3s ease 0.5s forwards;
}
@keyframes root-fade-in {
  to { opacity: 1; }
}
</style>
