/**
 * SSE event payload types matching the Go backend (internal/handler/sse.go).
 *
 * Event format on the wire:
 *   event: <eventType>
 *   data: <json>
 *
 * The types below define the backend contract. The SSEPayloadMap maps
 * each event type string to its expected payload shape. SSEMessage is a
 * discriminated union on `type` — when you switch on msg.type, TypeScript
 * narrows msg.data to the correct payload interface automatically.
 */

import type { AgentStatus } from '../types'

/** agent.status — agent came online, went offline, changed state */
export interface AgentStatusEvent {
  agentId: string
  status: AgentStatus
  /** Optional human-readable reason (e.g. error message) */
  reason?: string
}

/** agent.task — a task was assigned to or completed by an agent */
export interface AgentTaskEvent {
  agentId: string
  taskId: string
  title: string
  action: 'assigned' | 'completed' | 'failed'
}

/** agent.progress — incremental progress update for a running task */
export interface AgentProgressEvent {
  agentId: string
  taskId: string
  progress: number
  /** Optional description of what is currently happening */
  message?: string
}

/**
 * fleet.update — bulk refresh of all agents (e.g. after a deployment).
 * The backend may send partial or complete agent state.
 */
export interface FleetUpdateEvent {
  /** ISO timestamp of when the snapshot was taken */
  timestamp: string
  /** Number of agents in the fleet */
  agentCount: number
}

/** Union of all SSE data payloads keyed by event type. */
export type SSEPayloadMap = {
  'agent.status': AgentStatusEvent
  'agent.task': AgentTaskEvent
  'agent.progress': AgentProgressEvent
  'fleet.update': FleetUpdateEvent
  connected: { clientCount: number }
  message: unknown
}

/**
 * Discriminated SSE message — the `type` field narrows `data` via SSEPayloadMap.
 *
 * Usage:
 *   if (msg.type === 'agent.status') {
 *     msg.data.agentId  // ✅ TypeScript knows this is AgentStatusEvent
 *   }
 */
export type SSEMessage = {
  [K in keyof SSEPayloadMap]: { type: K; data: SSEPayloadMap[K] }
}[keyof SSEPayloadMap]
