// Client-side feature-flag helper. One bulk eval per session, shared across
// every component via module-level state. Hits POST /api/flags/evaluate —
// the portal-side proxy derives the tenant from the signed-in user's JWT
// so callers don't pass a slug.
//
// Usage:
//   const enabled = useFeatureFlag('new_inbox_view')
//   <NewInbox v-if="enabled" />
//
// Multi-key:
//   const { flags, ready, refresh } = useFeatureFlags()
//   ready  → ref<boolean>  true once the first eval has resolved
//   flags  → ref<{ key: boolean }>
//   refresh() → re-fetch (e.g. after an admin flipped a flag while the user is
//               online; rare, mostly useful in long-lived sessions)
//
// The composable is intentionally NOT a Promise-returning function. It
// returns refs that update once the bulk eval lands; consumers can
// `<template v-if="enabled">` and the panel appears when the answer comes in.
// Flags evaluated before the first response are reactive `false`, so a
// gated feature stays hidden during the (typically <50ms) round-trip.

type FlagMap = Record<string, boolean>

// Singleton state shared by every caller in the app.
const flags = ref<FlagMap>({})
const ready = ref(false)
const pending = ref(false)
let inflight: Promise<FlagMap> | null = null

async function load(): Promise<FlagMap> {
  if (inflight) return inflight
  pending.value = true
  inflight = $fetch<FlagMap>('/api/flags/evaluate', { method: 'POST' })
    .then((map) => {
      flags.value = map ?? {}
      ready.value = true
      return flags.value
    })
    .catch((err) => {
      // Eval failures shouldn't break the app — every flag stays `false`
      // (fail-closed). Surface to the console for debugging.
      // eslint-disable-next-line no-console
      console.warn('[useFeatureFlag] eval failed', err)
      ready.value = true
      return flags.value
    })
    .finally(() => {
      pending.value = false
      inflight = null
    })
  return inflight
}

export const useFeatureFlags = () => {
  // Kick off the first load lazily. Safe to call from setup — `$fetch` will
  // resolve client-side; on SSR we just don't have a session yet anyway.
  if (import.meta.client && !ready.value && !pending.value) {
    void load()
  }
  return {
    flags,
    ready,
    pending,
    refresh: load,
  }
}

export const useFeatureFlag = (key: string): ComputedRef<boolean> => {
  // Touch the loader so single-key consumers don't have to import useFeatureFlags.
  if (import.meta.client && !ready.value && !pending.value) {
    void load()
  }
  return computed(() => flags.value[key] === true)
}
