// ═══════════════════════════════════════════════════════════
// WebSocket Types — from CONTRACTS.md §1.6
// ═══════════════════════════════════════════════════════════

import type { Pipeline, PipelineStage } from "./pipeline.js";
import type { Task, TaskDecision, TestResults } from "./task.js";
import type { AgentStatus, AgentHealth } from "./agent.js";

// ─── Channel Types ───

export type WsChannel =
  | "pipeline:*"
  | `pipeline:${string}`
  | "tasks:*"
  | "tasks:pending"
  | "agents:*"
  | "agents:health"
  | "deploys:*"
  | "notifications:me";

// ─── Client → Server Messages ───

export interface WsSubscribe {
  type: "subscribe";
  channels: WsChannel[];
}

export interface WsUnsubscribe {
  type: "unsubscribe";
  channels: WsChannel[];
}

export interface WsPing {
  type: "ping";
}

// ─── Server → Client Messages ───

export interface WsEvent<T = unknown> {
  type: WebSocketEventType;
  timestamp: string;
  channel: WsChannel;
  data: T;
}

export interface WsSubscribed {
  type: "subscribed";
  channels: WsChannel[];
}

export interface WsPong {
  type: "pong";
}

// ─── Event Types ───

export type WebSocketEventType =
  | "pipeline.created"
  | "pipeline.updated"
  | "pipeline.stage_changed"
  | "pipeline.completed"
  | "pipeline.failed"
  | "pipeline.blocked"
  | "task.created"
  | "task.claimed"
  | "task.completed"
  | "task.sla_warning"
  | "task.sla_breached"
  | "task.escalated"
  | "approval.pending"
  | "approval.approved"
  | "approval.rejected"
  | "agent.status_changed"
  | "agent.heartbeat"
  | "asset.created"
  | "asset.updated"
  | "deploy.started"
  | "deploy.succeeded"
  | "deploy.failed"
  | "feedback.received"
  | "feedback.processed";

// ─── Event Payloads ───

export interface PipelineCreatedPayload {
  pipeline: Pipeline;
}

export interface PipelineStageChangedPayload {
  pipelineId: string;
  pipelineName: string;
  fromStage: PipelineStage;
  toStage: PipelineStage;
  triggeredBy: string;
}

export interface PipelineBlockedPayload {
  pipelineId: string;
  pipelineName: string;
  blockedAt: PipelineStage;
  reason: string;
  taskId: string;
}

export interface TaskCreatedPayload {
  task: Task;
}

export interface TaskCompletedPayload {
  task: Task;
  decision: TaskDecision;
  decidedBy: string;
}

export interface TaskSlaPayload {
  taskId: string;
  taskTitle: string;
  pipelineId: string | null;
  slaDeadline: string;
  minutesRemaining: number;
  escalationLevel: number;
}

export interface AgentStatusPayload {
  agentId: string;
  agentName: string;
  fromStatus: AgentStatus;
  toStatus: AgentStatus;
  currentTaskId: string | null;
}

export interface AgentHeartbeatPayload {
  agentId: string;
  agentName: string;
  status: AgentStatus;
  health: AgentHealth;
}

export interface DeployPayload {
  pipelineId: string;
  pipelineName: string;
  target: "staging" | "production";
  version: string;
  status: "started" | "succeeded" | "failed";
  url?: string;
  error?: string;
}

export interface FeedbackReceivedPayload {
  feedbackId: string;
  pipelineId: string | null;
  modalType: string;
  decision: string | null;
}

/** Server deployment info */
export interface ServerStatus {
  name: string;
  pipelineId: string;
  stage: PipelineStage;
  health: "healthy" | "degraded" | "failing" | "unknown";
  deployments: {
    staging: DeploymentInfo | null;
    production: DeploymentInfo | null;
  };
  lastTestRun: TestResults | null;
  metrics: Record<string, number>;
}

export interface DeploymentInfo {
  version: string;
  deployedAt: string;
  url: string;
  status: "running" | "stopped" | "failed";
}
