/**
 * AWOOOI SSE 狀態機
 * ==========================
 * Phase 19.S - 7-State SSE Connection State Machine
 *
 * 設計原則:
 * 1. 明確的狀態轉換規則
 * 2. 防止非法狀態組合
 * 3. 支援斷線重連 + Last-Event-ID
 *
 * @see ADR-031 Omni-Terminal SSE Architecture
 * @see docs/meetings/2026-03-27-phase19-omni-terminal-brainstorm.md
 *
 * @author Claude Code (首席架構師)
 * @version 1.0.0
 * @date 2026-03-28 (台北時間)
 */

// =============================================================================
// SSE 連線狀態 (7 States)
// =============================================================================

/**
 * SSE 連線狀態枚舉
 *
 * 狀態流程:
 * ```
 * disconnected → connecting → subscribing → connected ⇄ streaming
 *       ↑              ↓                         ↓
 *       └────── error ←──────────────────────────┘
 *                 ↓
 *          reconnecting → connecting ...
 * ```
 */
export type SSEConnectionState =
  | 'disconnected'   // 未連接 (初始狀態)
  | 'connecting'     // 正在連接 (POST intent)
  | 'subscribing'    // 訂閱中 (GET stream)
  | 'connected'      // 已連接 (空閒，等待輸入)
  | 'streaming'      // 串流中 (AI 正在回應)
  | 'reconnecting'   // 重連中 (斷線後)
  | 'error'          // 錯誤狀態

// =============================================================================
// 狀態轉換規則
// =============================================================================

/**
 * 合法的狀態轉換表
 * key: 當前狀態
 * value: 允許轉換到的狀態列表
 */
export const VALID_TRANSITIONS: Record<SSEConnectionState, SSEConnectionState[]> = {
  disconnected: ['connecting'],
  connecting: ['subscribing', 'error', 'disconnected'],
  subscribing: ['connected', 'error'],
  connected: ['streaming', 'reconnecting', 'disconnected'],
  streaming: ['connected', 'error'],
  reconnecting: ['connecting', 'error', 'disconnected'],
  error: ['reconnecting', 'disconnected'],
}

/**
 * 檢查狀態轉換是否合法
 */
export function isValidTransition(
  from: SSEConnectionState,
  to: SSEConnectionState
): boolean {
  return VALID_TRANSITIONS[from].includes(to)
}

/**
 * 嘗試狀態轉換，非法則拋出錯誤
 */
export function assertValidTransition(
  from: SSEConnectionState,
  to: SSEConnectionState
): void {
  if (!isValidTransition(from, to)) {
    throw new Error(
      `[SSE] Invalid state transition: ${from} → ${to}. ` +
      `Allowed: ${VALID_TRANSITIONS[from].join(', ')}`
    )
  }
}

// =============================================================================
// 狀態屬性
// =============================================================================

/**
 * 狀態屬性定義
 */
export interface SSEStateInfo {
  /** 狀態名稱 */
  label: string
  /** 是否正在載入 */
  isLoading: boolean
  /** 是否已連接 (可發送訊息) */
  isConnected: boolean
  /** 是否正在串流 */
  isStreaming: boolean
  /** 是否為錯誤狀態 */
  isError: boolean
  /** 狀態顏色 (Tailwind class) */
  color: string
}

/**
 * 狀態資訊對照表
 *
 * Note: label 是 i18n key (connection.xxx)，使用時需呼叫 t(label)
 * 修復: 2026-03-29 Wave 3 i18n 清零
 */
export const SSE_STATE_INFO: Record<SSEConnectionState, SSEStateInfo> = {
  disconnected: {
    label: 'disconnected',  // i18n: connection.disconnected
    isLoading: false,
    isConnected: false,
    isStreaming: false,
    isError: false,
    color: 'text-gray-400',
  },
  connecting: {
    label: 'connecting',  // i18n: connection.connecting
    isLoading: true,
    isConnected: false,
    isStreaming: false,
    isError: false,
    color: 'text-yellow-500',
  },
  subscribing: {
    label: 'subscribing',  // i18n: connection.subscribing
    isLoading: true,
    isConnected: false,
    isStreaming: false,
    isError: false,
    color: 'text-yellow-500',
  },
  connected: {
    label: 'connected',  // i18n: connection.connected
    isLoading: false,
    isConnected: true,
    isStreaming: false,
    isError: false,
    color: 'text-green-500',
  },
  streaming: {
    label: 'streaming',  // i18n: connection.streaming
    isLoading: false,
    isConnected: true,
    isStreaming: true,
    isError: false,
    color: 'text-claw-blue',
  },
  reconnecting: {
    label: 'reconnecting',  // i18n: connection.reconnecting
    isLoading: true,
    isConnected: false,
    isStreaming: false,
    isError: false,
    color: 'text-orange-500',
  },
  error: {
    label: 'error',  // i18n: connection.error
    isLoading: false,
    isConnected: false,
    isStreaming: false,
    isError: true,
    color: 'text-red-500',
  },
}

/**
 * 取得狀態資訊
 */
export function getStateInfo(state: SSEConnectionState): SSEStateInfo {
  return SSE_STATE_INFO[state]
}

// =============================================================================
// 重連策略
// =============================================================================

/**
 * 重連設定
 */
export const RECONNECT_CONFIG = {
  /** 初始延遲 (ms) */
  INITIAL_DELAY: 1000,
  /** 最大延遲 (ms) */
  MAX_DELAY: 16000,
  /** 最大重試次數 */
  MAX_RETRIES: 5,
  /** 延遲倍數 (指數退避) */
  BACKOFF_MULTIPLIER: 2,
} as const

/**
 * 計算重連延遲 (指數退避)
 * @param attempt - 第幾次重試 (0-based)
 * @returns 延遲毫秒數
 */
export function getReconnectDelay(attempt: number): number {
  const delay = RECONNECT_CONFIG.INITIAL_DELAY *
    Math.pow(RECONNECT_CONFIG.BACKOFF_MULTIPLIER, attempt)
  return Math.min(delay, RECONNECT_CONFIG.MAX_DELAY)
}

/**
 * 是否應該繼續重試
 */
export function shouldRetry(attempt: number): boolean {
  return attempt < RECONNECT_CONFIG.MAX_RETRIES
}

// =============================================================================
// SSE 事件類型 (前端)
// =============================================================================

/**
 * Terminal SSE 事件類型
 * 對應後端 EventType
 */
export type TerminalEventType =
  // 思考軌跡
  | 'terminal_thought'
  | 'terminal_tool_call'
  // GenUI
  | 'terminal_render_ui'
  // 授權
  | 'terminal_action_request'
  | 'terminal_action_result'
  // 控制
  | 'terminal_complete'
  | 'terminal_error'
  | 'terminal_heartbeat'
  // 標準 SSE
  | 'connected'
  | 'heartbeat'

/**
 * SSE 事件資料結構
 */
export interface SSEEventData {
  type: TerminalEventType
  data: Record<string, unknown>
  id?: string
  timestamp?: string
}

// =============================================================================
// Session 管理
// =============================================================================

/**
 * Terminal Session 狀態
 */
export interface TerminalSession {
  /** Session ID */
  sessionId: string
  /** 最後事件 ID (用於斷點續傳) */
  lastEventId: string | null
  /** 建立時間 */
  createdAt: Date
  /** 最後活動時間 */
  lastActivityAt: Date
}

/**
 * 建立新 Session
 */
export function createSession(sessionId: string): TerminalSession {
  const now = new Date()
  return {
    sessionId,
    lastEventId: null,
    createdAt: now,
    lastActivityAt: now,
  }
}
