/**
 * Auto-connect the staff-chat WebSocket once the app is up — but ONLY for
 * non-limited staff and ONLY when the chat module is enabled. Limited ('c')
 * roles and disabled-chat builds never open a socket.
 *
 * Mirrors plugins/03.notifications-stream.client.ts (delayed start so we're past
 * initial hydration). Defensive: any failure here is swallowed so it can never
 * affect app boot.
 *
 * Eligibility is resolved against the SERVER (resolveChatEligible) rather than the
 * cookie, so a colleague who got IsChatEnabled set after their last login connects
 * without re-logging-in. That call also refreshes an expired token cookie, so the
 * socket below connects with a fresh token on its first try (no red-dot dance).
 * Unread badge counts are (re)seeded inside useChatSocket on every 'connected'
 * frame, so they no longer need a separate call here.
 *
 * Also consumes the /?chat=<userId> deep-link that chat push notifications target
 * (buildChatMessagePayload → sw-notifications.js openWindow): on it, open the
 * drawer on that conversation. Chat-only code → isolation preserved.
 */

export default defineNuxtPlugin((nuxtApp) => {
  if (!process.client) return

  try {
    // Cheapest synchronous short-circuit: a disabled build never connects.
    if (useRuntimeConfig().public.chatEnabled !== true) return

    let bootstrapped = false   // socket up — permanent once eligible
    let bootstrapping = false  // in-flight guard against concurrent navigations

    // Resolve eligibility against the server and, if eligible, open the socket.
    // useChatSocket() is captured HERE (not at plugin init) so its `me` is read from
    // the *logged-in* user cookie: the plugin runs once at app boot — on a fresh
    // login that's the signin page (no user cookie yet), so a handle captured then
    // would carry me=0 and mis-route every inbound message.
    const bootstrap = async () => {
      if (bootstrapped || bootstrapping) return
      bootstrapping = true
      try {
        const eligible = await resolveChatEligible()
        if (!eligible) return
        bootstrapped = true

        const { connect } = useChatSocket()
        connect()

        // Open the drawer on the conversation named by /?chat=<userId> (push
        // click target), and on any later in-app navigation to the same param.
        const route = useRoute()
        const openFromQuery = (val: any) => {
          const id = Number(val)
          if (!id) return
          useChatOpen().value = true
          useChatActivePeer().value = id
        }
        openFromQuery(route.query.chat)
        watch(() => route.query.chat, (val) => openFromQuery(val))
      } catch (e) {
        console.error('[ChatSocketPlugin] connect failed:', e)
      } finally {
        bootstrapping = false
      }
    }

    // First attempt, past initial hydration. Covers a logged-in reload / deep link.
    setTimeout(() => nuxtApp.runWithContext(() => bootstrap()), 2000)

    // Re-attempt after an SPA login. The plugin runs ONCE per page load; on a fresh
    // login the app boots logged-out (signin page), so the first attempt resolves
    // "not eligible". Every later navigation that lands while still un-bootstrapped
    // clears any stale logged-out verdict and retries with the now-present login
    // cookies — so the chat icon AND socket come up without a manual page reload.
    // Cheap no-op once bootstrapped; while logged-out resolveChatEligible()
    // short-circuits client-side (no server round-trip per navigation).
    useRouter().afterEach(() => {
      if (bootstrapped) return
      nuxtApp.runWithContext(() => {
        const resolved = useState<boolean | null>('chatEligibleResolved')
        if (resolved.value === false) resolved.value = null
        return bootstrap()
      })
    })
  } catch (e) {
    console.error('[ChatSocketPlugin] init skipped:', e)
  }
})
