import { useNodeStatus } from './useNodeStatus';

/**
 * Pet animation states surfaced by the node-status feed.
 *
 * Phase C resolves only the two coarse states the BackendStatusRegistry
 * can derive deterministically: 'running' when at least one slot on the
 * node is busy, 'idle' otherwise. The vocabulary is intentionally kept
 * small so future expansion ('cache-hit', 'thinking', etc.) can be added
 * without churning every call site — the union type already grants
 * widening room for those without breaking existing consumers if they
 * fall through to an 'idle' default.
 */
export type NodeAnimationState = 'idle' | 'running';

/**
 * Resolve a node's pet-animation state from the registry feed.
 *
 * - When `nodeId` is null/undefined, returns 'idle' (no node to track).
 * - When the registry has not yet observed the node (first probe still
 *   in flight, proxy-backend that hasn't surfaced yet, or a workerId
 *   for a worker not in the latest snapshot), returns 'idle' as a
 *   conservative fallback. The PetSprite will animate at idle cadence
 *   until the first real status arrives.
 * - When the node is reachable AND has at least one busy slot, returns
 *   'running'. This deliberately ignores `online === false` (offline →
 *   idle, not error) so the pet doesn't aggressively flap whenever a
 *   probe times out; the NodeStatusWidget surfaces probe errors via its
 *   own badge column.
 *
 * The underlying useNodeStatus query is shared across all consumers via
 * React Query's queryKey dedup, so calling this hook from N rows in the
 * NodeStatusWidget plus the ChatPetOverlay does not multiply the HTTP
 * polling rate.
 */
export function useNodeAnimationState(nodeId: string | null | undefined): NodeAnimationState {
  const { nodes } = useNodeStatus();
  if (!nodeId) return 'idle';
  const node = nodes.find((n) => n.nodeId === nodeId);
  if (!node) return 'idle';
  return node.busy ? 'running' : 'idle';
}
