/**
 * Event Types and Interfaces for SSE
 *
 * These types mirror the backend event schemas from backend/app/schemas/events.py
 * for type-safe event handling in the frontend.
 *
 * @module lib/types/events
 */

// ============================================================================
// Event Type Enum
// ============================================================================

/**
 * Event types matching backend EventType enum.
 * Naming convention: {domain}.{action}
 */
export enum EventType {
  // Agent Events
  AGENT_SPAWNED = 'agent.spawned',
  AGENT_STATUS_CHANGED = 'agent.status_changed',
  AGENT_MESSAGE = 'agent.message',
  AGENT_TERMINATED = 'agent.terminated',

  // Issue Events
  ISSUE_CREATED = 'issue.created',
  ISSUE_UPDATED = 'issue.updated',
  ISSUE_ASSIGNED = 'issue.assigned',
  ISSUE_CLOSED = 'issue.closed',

  // Sprint Events
  SPRINT_STARTED = 'sprint.started',
  SPRINT_COMPLETED = 'sprint.completed',

  // Approval Events
  APPROVAL_REQUESTED = 'approval.requested',
  APPROVAL_GRANTED = 'approval.granted',
  APPROVAL_DENIED = 'approval.denied',

  // Project Events
  PROJECT_CREATED = 'project.created',
  PROJECT_UPDATED = 'project.updated',
  PROJECT_ARCHIVED = 'project.archived',

  // Workflow Events
  WORKFLOW_STARTED = 'workflow.started',
  WORKFLOW_STEP_COMPLETED = 'workflow.step_completed',
  WORKFLOW_COMPLETED = 'workflow.completed',
  WORKFLOW_FAILED = 'workflow.failed',
}

// ============================================================================
// Actor Types
// ============================================================================

/**
 * Type of actor who triggered an event
 */
export type ActorType = 'agent' | 'user' | 'system';

// ============================================================================
// Base Event Interface
// ============================================================================

/**
 * Base event schema matching backend Event model.
 * All events from the EventBus conform to this schema.
 */
export interface ProjectEvent {
  /** Unique event identifier (UUID string) */
  id: string;
  /** Event type enum value */
  type: EventType;
  /** When the event occurred (ISO 8601 UTC) */
  timestamp: string;
  /** Project this event belongs to (UUID string) */
  project_id: string;
  /** ID of the agent or user who triggered the event (UUID string) */
  actor_id: string | null;
  /** Type of actor: 'agent', 'user', or 'system' */
  actor_type: ActorType;
  /** Event-specific payload data */
  payload: EventPayload;
}

// ============================================================================
// Payload Types
// ============================================================================

/**
 * Union type for all possible event payloads
 */
export type EventPayload =
  | AgentSpawnedPayload
  | AgentStatusChangedPayload
  | AgentMessagePayload
  | AgentTerminatedPayload
  | IssueCreatedPayload
  | IssueUpdatedPayload
  | IssueAssignedPayload
  | IssueClosedPayload
  | SprintStartedPayload
  | SprintCompletedPayload
  | ApprovalRequestedPayload
  | ApprovalGrantedPayload
  | ApprovalDeniedPayload
  | WorkflowStartedPayload
  | WorkflowStepCompletedPayload
  | WorkflowCompletedPayload
  | WorkflowFailedPayload
  | Record<string, unknown>;

// Agent Payloads

export interface AgentSpawnedPayload {
  agent_instance_id: string;
  agent_type_id: string;
  agent_name: string;
  role: string;
}

export interface AgentStatusChangedPayload {
  agent_instance_id: string;
  previous_status: string;
  new_status: string;
  reason?: string | null;
}

export interface AgentMessagePayload {
  agent_instance_id: string;
  message: string;
  message_type: 'info' | 'warning' | 'error' | 'debug';
  metadata?: Record<string, unknown>;
}

export interface AgentTerminatedPayload {
  agent_instance_id: string;
  termination_reason: string;
  final_status: string;
}

// Issue Payloads

export interface IssueCreatedPayload {
  issue_id: string;
  title: string;
  priority?: string | null;
  labels?: string[];
}

export interface IssueUpdatedPayload {
  issue_id: string;
  changes: Record<string, unknown>;
}

export interface IssueAssignedPayload {
  issue_id: string;
  assignee_id?: string | null;
  assignee_name?: string | null;
}

export interface IssueClosedPayload {
  issue_id: string;
  resolution: string;
}

// Sprint Payloads

export interface SprintStartedPayload {
  sprint_id: string;
  sprint_name: string;
  goal?: string | null;
  issue_count?: number;
}

export interface SprintCompletedPayload {
  sprint_id: string;
  sprint_name: string;
  completed_issues?: number;
  incomplete_issues?: number;
}

// Approval Payloads

export interface ApprovalRequestedPayload {
  approval_id: string;
  approval_type: string;
  description: string;
  requested_by?: string | null;
  timeout_minutes?: number | null;
}

export interface ApprovalGrantedPayload {
  approval_id: string;
  approved_by: string;
  comments?: string | null;
}

export interface ApprovalDeniedPayload {
  approval_id: string;
  denied_by: string;
  reason: string;
}

// Workflow Payloads

export interface WorkflowStartedPayload {
  workflow_id: string;
  workflow_type: string;
  total_steps?: number;
}

export interface WorkflowStepCompletedPayload {
  workflow_id: string;
  step_name: string;
  step_number: number;
  total_steps: number;
  result?: Record<string, unknown>;
}

export interface WorkflowCompletedPayload {
  workflow_id: string;
  duration_seconds: number;
  result?: Record<string, unknown>;
}

export interface WorkflowFailedPayload {
  workflow_id: string;
  error_message: string;
  failed_step?: string | null;
  recoverable?: boolean;
}

// ============================================================================
// Type Guards
// ============================================================================

/**
 * Type guard to check if an event is a specific type
 */
export function isEventType<T extends EventType>(
  event: ProjectEvent,
  type: T
): event is ProjectEvent & { type: T } {
  return event.type === type;
}

/**
 * Type guard for agent events
 */
export function isAgentEvent(event: ProjectEvent): boolean {
  return event.type.startsWith('agent.');
}

/**
 * Type guard for issue events
 */
export function isIssueEvent(event: ProjectEvent): boolean {
  return event.type.startsWith('issue.');
}

/**
 * Type guard for sprint events
 */
export function isSprintEvent(event: ProjectEvent): boolean {
  return event.type.startsWith('sprint.');
}

/**
 * Type guard for approval events
 */
export function isApprovalEvent(event: ProjectEvent): boolean {
  return event.type.startsWith('approval.');
}

/**
 * Type guard for workflow events
 */
export function isWorkflowEvent(event: ProjectEvent): boolean {
  return event.type.startsWith('workflow.');
}

/**
 * Type guard for project events
 */
export function isProjectEvent(event: ProjectEvent): boolean {
  return event.type.startsWith('project.');
}

// ============================================================================
// SSE Connection Types
// ============================================================================

/**
 * Connection state for SSE
 */
export type ConnectionState = 'connecting' | 'connected' | 'disconnected' | 'error';

/**
 * SSE error information
 */
export interface SSEError {
  message: string;
  code?: string;
  timestamp: string;
  retryAttempt?: number;
}
