/**
 * 事件相关类型定义
 * @module types/events
 */

/**
 * 事件枚举
 * 定义 JSSDK 中所有可触发的事件类型
 * 
 * @example
 * ```typescript
 * import { EmitEvent } from 'qt-human'
 * 
 * human.on(EmitEvent.HUMAN_READY, () => {
 *   console.log('数字人已准备就绪')
 * })
 * 
 * human.on(EmitEvent.HUMAN_ERROR, (error) => {
 *   console.error('发生错误:', error)
 * })
 * ```
 */
export enum EmitEvent {
  // ==================== Human 对象生命周期事件 ====================
  
  /** 
   * Human 对象加载完成，可以开始使用
   * 
   * 触发时机：模型加载完成，所有资源准备就绪
   * 
   * 事件数据：无
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.HUMAN_READY, () => {
   *   console.log('数字人已准备就绪')
   *   human.speak('你好，我已经准备好了')
   * })
   * ```
   */
  HUMAN_READY = 'human.ready',
  
  /** 
   * Human 对象发生错误
   * 
   * 触发时机：任何错误发生时
   * 
   * 事件数据：ErrorEvent
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.HUMAN_ERROR, (error) => {
   *   console.error('错误代码:', error.code)
   *   console.error('错误消息:', error.message)
   * })
   * ```
   */
  HUMAN_ERROR = 'human.error',
  
  /** 
   * Human 对象触发指令动作
   * 
   * 触发时机：
   * 1. 从 askCommand 方法接收到动作指令时
   * 2. 从 Gateway 服务接收到角色动作消息（CMD: 1020）时
   * 
   * 事件数据：CharacterActionEvent | string[]
   * - CharacterActionEvent: 包含动作名称和参数的完整对象（来自 Gateway 1020）
   * - string[]: 动作名称数组（来自 askCommand，兼容旧格式）
   * 
   * @example
   * ```typescript
   * // 处理来自 Gateway 的角色动作（CMD: 1020）
   * human.on(EmitEvent.HUMAN_ACTION_PENDING, (data) => {
   *   if (typeof data === 'object' && 'name' in data) {
   *     console.log('动作名称:', data.name)
   *     console.log('动作参数:', data.inputs)
   *     // 例如: { name: '[#play#]', inputs: { target: 'xx' } }
   *   } else {
   *     // 兼容旧格式
   *     console.log('待执行的动作:', data)
   *   }
   * })
   * ```
   */
  HUMAN_ACTION_PENDING = 'human.action.pending',
  
  /** 
   * Human 对象加载进度更新
   * 
   * 触发时机：模型加载过程中
   * 
   * 事件数据：LoadProgressEvent
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.HUMAN_LOAD_PROGRESS, (data) => {
   *   const percentage = (data.progress / data.total * 100).toFixed(2)
   *   console.log(`加载进度: ${percentage}%`)
   *   updateProgressBar(percentage)
   * })
   * ```
   */
  HUMAN_LOAD_PROGRESS = 'human.load.progress',
  
  /** 
   * 核心模型包加载完成
   * 
   * 触发时机：所有核心模型文件加载完成
   * 
   * 事件数据：any[]
   */
  CORE_BUNDLES_LOADED = 'core.bundles.loaded',
  
  // ==================== 音频播放事件 ====================
  
  /** 
   * 音频开始播放
   * 
   * 触发时机：音频开始播放时
   * 
   * 事件数据：AudioPlayEvent
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.AUDIO_PLAY, () => {
   *   console.log('音频开始播放')
   *   showPlayingIcon()
   * })
   * ```
   */
  AUDIO_PLAY = 'audio.play',
  
  /** 
   * 音频暂停播放
   * 
   * 触发时机：音频暂停或停止时
   * 
   * 事件数据：AudioPlayEvent
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.AUDIO_PAUSE, () => {
   *   console.log('音频已暂停')
   *   hidePlayingIcon()
   * })
   * ```
   */
  AUDIO_PAUSE = 'audio.pause',
  
  // ==================== 录音相关事件 ====================
  
  /** 录音器消息 */
  RECORDER_MESSAGE = 'recorder.message',
  
  /** 录音开始 */
  RECORDER_START = 'recorder.start',
  
  /** 录音结束 */
  RECORDER_STOP = 'recorder.stop',
  
  /** 发送录音数据到 ASR 服务 */
  RECORDER_SENDING = 'recorder.sending',
  
  // ==================== 语音交互事件 ====================
  
  /** 语音交互进入睡眠模式 */
  VOICE_SLEEP = 'voice.sleep',
  
  /** 语音交互被唤醒 */
  VOICE_WAKE = 'voice.wake',
  
  /** 语音交互被打断 */
  VOICE_INTERRUPT = 'voice.interrupt',

  /** TTS 播放期间用户打断（Barge-in） */
  VOICE_BARGE_IN = 'voice.barge_in',

  /** 语音转文本结果 */
  VOICE2TEXT = 'voice2text',
  
  /** 唤醒状态下开始录音 */
  WAKE_RECORDER_START = 'wake.record.start',
  
  /** 唤醒状态下结束录音 */
  WAKE_RECORDER_STOP = 'wake.record.stop',
  
  // ==================== 对话和 TTS 事件 ====================
  
  /** 对话消息的 BlendShapes 动画开始播放 */
  CHAT_MESSAGE_BS_PLAY_START = 'chat.message.bs.play.start',
  
  /** 对话消息的 BlendShapes 动画结束播放 */
  CHAT_MESSAGE_BS_PLAY_END = 'chat.message.bs.play.end',
  
  // ==================== Gateway 服务事件 ====================
  
  /** 
   * Gateway WebSocket 连接成功
   * 
   * 触发时机：Gateway WebSocket 连接建立成功
   * 
   * 事件数据：无
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.GATEWAY_CONNECTED, () => {
   *   console.log('Gateway 服务已连接')
   *   showConnectionStatus('connected')
   * })
   * ```
   */
  GATEWAY_CONNECTED = 'gateway.connected',
  
  /** 
   * Gateway WebSocket 断开连接
   * 
   * 触发时机：Gateway WebSocket 连接断开
   * 
   * 事件数据：无
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.GATEWAY_DISCONNECTED, () => {
   *   console.log('Gateway 服务已断开')
   *   showConnectionStatus('disconnected')
   * })
   * ```
   */
  GATEWAY_DISCONNECTED = 'gateway.disconnected',
  
  /** 
   * Gateway WebSocket 正在重连
   * 
   * 触发时机：Gateway WebSocket 尝试重新连接时
   * 
   * 事件数据：无
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.GATEWAY_RECONNECTING, () => {
   *   console.log('Gateway 服务正在重连...')
   *   showConnectionStatus('reconnecting')
   * })
   * ```
   */
  GATEWAY_RECONNECTING = 'gateway.reconnecting',
  
  /** 
   * Gateway 接收到消息
   * 
   * 触发时机：从 Gateway 接收到任何消息时
   * 
   * 事件数据：GatewayMessageEvent
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.GATEWAY_MESSAGE, (data) => {
   *   console.log('收到 Gateway 消息:', data.type, data.event)
   * })
   * ```
   */
  GATEWAY_MESSAGE = 'gateway.message',
  
  /** 
   * Gateway 发生错误
   * 
   * 触发时机：Gateway 服务发生错误时
   * 
   * 事件数据：ErrorEvent
   * 
   * @example
   * ```typescript
   * human.on(EmitEvent.GATEWAY_ERROR, (error) => {
   *   console.error('Gateway 错误:', error.message)
   *   showConnectionStatus('error')
   * })
   * ```
   */
  GATEWAY_ERROR = 'gateway.error',

  /**
   * Gateway 主动推送会话状态（CMD 1030）。
   * 目前典型场景：播完退出语后服务端将会话置为 SLEEPING 并下发 { state: 'SLEEPING', reason: 'graceful_exit' }，
   * 前端据此同步 UI 与状态机，无需依赖超时或二次唤醒。
   *
   * @example
   * ```typescript
   * human.on(EmitEvent.GATEWAY_STATE_PUSH, ({ state, reason }) => {
   *   if (state === 'SLEEPING') showSleepingUI()
   * })
   * ```
   */
  GATEWAY_STATE_PUSH = 'gateway.state.push',

  // ==================== 摄像头相关事件 ====================
  
  /** 摄像头人体检测结果 */
  CAMERA_PERSON_TEST_RESULT = 'camera.person.test.result',
  
  /** 摄像头人脸识别结果 */
  CAMERA_FACE_RECOGNITION_RESULT = 'camera.face.recognition.result',
  
  // ==================== 渲染相关事件 ====================
  
  /** 渲染服务初始化完成 */
  RENDER_READY = 'render.ready',
  
  /** 渲染服务发生错误 */
  RENDER_ERROR = 'render.error',
  
  /** 模型加载进度更新 */
  MODEL_LOAD_PROGRESS = 'model.load.progress',
  
  /** 模型加载完成 */
  MODEL_LOADED = 'model.loaded',
  
  /** 模型加载失败 */
  MODEL_LOAD_FAILED = 'model.load.failed',
  
  /** 动画播放开始 */
  ANIMATION_START = 'animation.start',
  
  /** 动画播放结束 */
  ANIMATION_END = 'animation.end',
}

/**
 * 加载进度事件数据
 * 
 * @example
 * ```typescript
 * human.on(EmitEvent.HUMAN_LOAD_PROGRESS, (data: LoadProgressEvent) => {
 *   const percentage = (data.progress / data.total * 100).toFixed(2)
 *   console.log(`${data.code}: ${percentage}%`)
 * })
 * ```
 */
export interface LoadProgressEvent {
  /** 
   * 进度代码
   * - `download`: 下载阶段
   * - `loaded`: 加载阶段
   * - `loading`: 加载中
   */
  code: 'download' | 'loaded' | 'loading';
  
  /** 
   * 当前进度值
   * @example 50
   */
  progress: number;
  
  /** 
   * 总进度值
   * @example 100
   */
  total: number;
  
  /** 
   * 资源 URL（可选）
   * 正在加载的资源地址
   */
  url?: string;
}

/**
 * 错误事件数据
 * 
 * @example
 * ```typescript
 * human.on(EmitEvent.HUMAN_ERROR, (error: ErrorEvent) => {
 *   console.error(`错误 [${error.code}]: ${error.message}`)
 *   if (error.details) {
 *     console.error('详情:', error.details)
 *   }
 * })
 * ```
 */
export interface ErrorEvent {
  /** 
   * 错误代码
   * 用于标识错误类型
   * @example 'GATEWAY_CONNECTION_FAILED'
   * @example 2001
   */
  code: string | number;
  
  /** 
   * 错误消息
   * 人类可读的错误描述
   * @example 'Failed to connect to Gateway service'
   */
  msg: string;
  
  /** 
   * 错误详情（可选）
   * 包含更多错误信息的对象
   */
  details?: any;
}

/**
 * 音频播放事件数据
 * 
 * @example
 * ```typescript
 * human.on(EmitEvent.AUDIO_PLAY, (data: AudioPlayEvent) => {
 *   console.log(`播放中: ${data.currentTime}/${data.duration}秒`)
 * })
 * ```
 */
export interface AudioPlayEvent {
  /** 
   * 是否正在播放
   */
  playing: boolean;
  
  /** 
   * 音频时长（秒）
   * @example 5.2
   */
  duration?: number;
  
  /** 
   * 当前播放时间（秒）
   * @example 2.5
   */
  currentTime?: number;
}

/**
 * 语音识别事件数据
 * 
 * @example
 * ```typescript
 * human.on(EmitEvent.VOICE2TEXT, (data: Voice2TextEvent) => {
 *   if (data.isFinal) {
 *     console.log('最终结果:', data.text)
 *     console.log('置信度:', data.confidence)
 *   } else {
 *     console.log('临时结果:', data.text)
 *   }
 * })
 * ```
 */
export interface Voice2TextEvent {
  /** 
   * 是否为最终结果
   * - `true`: 最终识别结果，不会再改变
   * - `false`: 临时识别结果，可能会更新
   */
  isFinal: boolean;
  
  /** 
   * 识别的文本内容
   * @example '你好，今天天气怎么样？'
   */
  text: string;
  
  /**
   * 识别置信度（可选）
   * 范围 0-1，值越大表示越可信
   * @example 0.95
   */
  confidence?: number;

  /**
   * 是否为打断触发的识别结果（可选）
   * - `true`: 这是用户打断 TTS 播放时的识别结果，框架已自动处理 LLM 请求（当 autoAsk=true 时）
   * - `false/undefined`: 普通识别结果
   *
   * 注意：当 isBargeIn=true 且 autoAsk=true 时，框架内部已经处理了 LLM 请求，
   * 外部代码不应该再次调用 askStream()，否则会导致重复发送
   * @since 3.5.2
   */
  isBargeIn?: boolean;
}

/**
 * 人脸识别结果
 */
export interface FaceRecognitionResult {
  /** 检测到的人脸数量 */
  count: number;
  /** 人脸信息列表 */
  faces: Array<{
    /** 置信度 */
    confidence: number;
    /** 边界框 */
    box: {
      x: number;
      y: number;
      width: number;
      height: number;
    };
    /** 特征点 */
    landmarks?: any[];
  }>;
}

/**
 * 人体检测结果
 */
export interface PersonDetectionResult {
  /** 检测到的人数 */
  count: number;
  /** 是否检测到人 */
  detected: boolean;
}

/**
 * Gateway 消息事件数据
 */
export interface GatewayMessageEvent {
  /** 消息类型 */
  type: 'chat' | 'tts' | 'asr' | 'error';
  /** 事件名称 */
  event: string;
  /** 消息数据 */
  data: any;
  /** 请求 ID */
  requestId?: string;
}

/**
 * 事件监听器类型
 */
export type EventListener<T = any> = (data: T) => void;

/**
 * 动画播放事件数据
 */
export interface AnimationEvent {
  /** 动画代码 */
  code: string;
  /** 动画名称 */
  name?: string;
  /** 动画时长（秒） */
  duration?: number;
}

/**
 * 模型加载事件数据
 */
export interface ModelLoadEvent {
  /** 模型代码 */
  code: string;
  /** 模型名称 */
  name: string;
  /** 模型类型 */
  type: 'apose' | 'animation' | 'animation_system';
  /** 加载进度 (0-100) */
  progress?: number;
}

/**
 * 角色动作事件数据
 * 对应 Gateway CMD: 1020
 */
export interface CharacterActionEvent {
  /** 动作名称列表（兼容旧格式） */
  actions: string[];
  /** 动作名称 */
  name: string;
  /** 动作额外参数 */
  inputs: Record<string, any>;
}

/**
 * 事件映射类型
 * 定义每个事件对应的数据类型
 */
export interface EventMap {
  // Human 生命周期事件
  [EmitEvent.HUMAN_READY]: void;
  [EmitEvent.HUMAN_ERROR]: ErrorEvent;
  [EmitEvent.HUMAN_LOAD_PROGRESS]: LoadProgressEvent;
  [EmitEvent.HUMAN_ACTION_PENDING]: CharacterActionEvent | string[];
  [EmitEvent.CORE_BUNDLES_LOADED]: any[];
  
  // 音频事件
  [EmitEvent.AUDIO_PLAY]: AudioPlayEvent;
  [EmitEvent.AUDIO_PAUSE]: AudioPlayEvent;
  
  // 录音事件
  [EmitEvent.RECORDER_MESSAGE]: any;
  [EmitEvent.RECORDER_START]: void;
  [EmitEvent.RECORDER_STOP]: void;
  [EmitEvent.RECORDER_SENDING]: void;
  
  // 语音交互事件
  [EmitEvent.VOICE_SLEEP]: void;
  [EmitEvent.VOICE_WAKE]: any;
  [EmitEvent.VOICE_INTERRUPT]: void;
  [EmitEvent.VOICE_BARGE_IN]: { text: string };
  [EmitEvent.VOICE2TEXT]: Voice2TextEvent;
  [EmitEvent.WAKE_RECORDER_START]: void;
  [EmitEvent.WAKE_RECORDER_STOP]: void;
  /** 显示打断提示 */
  [EmitEvent.VOICE_INTERRUPT_HINT_SHOW]: { words: string[] };
  /** 隐藏打断提示 */
  [EmitEvent.VOICE_INTERRUPT_HINT_HIDE]: void;
  /** 语音打断成功 */
  [EmitEvent.VOICE_INTERRUPTED]: { text: string; feedback: string };
  
  // 对话和 TTS 事件
  [EmitEvent.CHAT_MESSAGE_BS_PLAY_START]: {
    reqId: string;
    content: string;
    conversationId: string;
    isEnd: boolean;
  };
  [EmitEvent.CHAT_MESSAGE_BS_PLAY_END]: {
    reqId: string;
    conversationId: string;
    isEnd: boolean;
  };
  
  // Gateway 事件
  [EmitEvent.GATEWAY_CONNECTED]: void;
  [EmitEvent.GATEWAY_DISCONNECTED]: void;
  [EmitEvent.GATEWAY_RECONNECTING]: void;
  [EmitEvent.GATEWAY_MESSAGE]: GatewayMessageEvent;
  [EmitEvent.GATEWAY_ERROR]: ErrorEvent;
  [EmitEvent.GATEWAY_STATE_PUSH]: {
    state: 'SLEEPING' | 'IDLE' | 'LISTENING' | 'THINKING' | 'SPEAKING' | 'COOLDOWN';
    reason?: string;
  };
  
  // 摄像头事件
  [EmitEvent.CAMERA_FACE_RECOGNITION_RESULT]: FaceRecognitionResult;
  [EmitEvent.CAMERA_PERSON_TEST_RESULT]: PersonDetectionResult;

  // 表情检测事件
  [EmitEvent.EXPRESSION_SMILE_DETECTED]: void;
  [EmitEvent.EXPRESSION_SMILE_STATE_CHANGED]: import('./camera').SmileStateData;

  // 渲染事件
  [EmitEvent.RENDER_READY]: void;
  [EmitEvent.RENDER_ERROR]: ErrorEvent;
  [EmitEvent.MODEL_LOAD_PROGRESS]: ModelLoadEvent;
  [EmitEvent.MODEL_LOADED]: ModelLoadEvent;
  [EmitEvent.MODEL_LOAD_FAILED]: ErrorEvent;
  [EmitEvent.ANIMATION_START]: AnimationEvent;
  [EmitEvent.ANIMATION_END]: AnimationEvent;
}
