import { useIsAuthenticated } from '@/hooks';
import { useMe } from './useMe';
import { toAppRoles } from '../routing';
import type { Me } from '../types';
import type { AppRole } from '@/constants';

/**
 * The resolved-vs-pending role state for a private route. The core refinement-phase-2 fix: a shell must
 * distinguish **"/me hasn't resolved yet"** from **"the user has no nurse/admin role"** — conflating the
 * two is what silently showed a nurse the customer app (a fresh `/me` in-flight fell through the
 * `DEFAULT_ROLE = customer` fallback). This exposes that distinction so `RoleGuard` can render a neutral
 * loading state while pending, an explicit error state when `/me` failed, and only route on a resolved
 * role set.
 *
 * `error` fires only when `/me` has no data at all; a background refetch that fails while we still hold a
 * cached identity keeps serving `ready` (don't downgrade a known nurse on a transient blip).
 *
 * `unauthenticated` closes the one state that could hang forever: `useMe` is gated on there being a
 * session, so without one it never runs, never errors, and never resolves — leaving the guard on a
 * splash with no exit. Saying so explicitly lets `RoleGuard` send the visitor to login instead.
 */
export type RoleHydration =
  | { status: 'loading' }
  | { status: 'unauthenticated' }
  | { status: 'error'; retry: () => void; isRetrying: boolean }
  | { status: 'ready'; me: Me; appRoles: AppRole[] };

export function useRoleHydration(): RoleHydration {
  const isAuthenticated = useIsAuthenticated();
  const { data: me, isError, isFetching, refetch } = useMe();

  if (me) return { status: 'ready', me, appRoles: toAppRoles(me.roles) };
  if (isError) return { status: 'error', retry: () => void refetch(), isRetrying: isFetching };
  if (!isAuthenticated) return { status: 'unauthenticated' };
  return { status: 'loading' };
}
