/**
 * Human 类相关类型定义
 */

import * as THREE from 'three';
import Emittery from 'emittery';
import {
  HumanConfig,
  AngleViewConfig,
  VoiceConfig,
} from './config';
import {
  Result,
  AskParams,
  AskResponse,
  AskStreamResponse,
  StreamAudioPlayInfo,
  TTSResponse,
  RecorderPermission,
  Voice2TextResult,
  CharacterModel,
  AskCallback,
  SpeakCallback,
  Voice2TextCallback,
} from './api';
import {
  ModelInfo,
  PlayActionOptions,
} from './model';
import {
  CameraConfig,
  FaceRecognitionConfig,
  SmileDetectionConfig,
} from './camera';

/**
 * Human 类接口
 * 数字人核心 API
 */
export interface IHuman extends Emittery {
  /** 数字人名称 */
  name: string;

  /**
   * Gateway session id (populated after CmdLoginSuccess / 1007).
   * Empty string before WS login completes. Read-only.
   */
  readonly sessionId: string;

  /**
   * Phase 1B-β.7: enable / disable server-push proactive TTS playback.
   *
   * When enabled, raw TTS audio frames pushed by gateway (without a client request,
   * e.g. proactive "hi 张老师" when camera spots a known user) are routed to the
   * internal FramePlayer for playback. Default OFF for back-compat.
   *
   * Safe to call after `init()`. Does not interfere with voiceConversation / sendTTS.
   */
  enableProactiveTTSPlayback(enable?: boolean): void;

  // ========== 模型管理 ==========

  /**
   * 设置数字人模型
   * @param characterId 数字人 ID
   * @param config 可选的配置参数
   * @returns Promise<boolean> 是否成功
   */
  setCharacter(characterId: string, config?: Partial<HumanConfig>): Promise<boolean>;

  /**
   * 设置数字人模型数据
   * @param characterId 数字人 ID
   * @returns Promise<boolean> 是否成功
   */
  setCharacterData(characterId: string): Promise<boolean>;

  /**
   * 获取模型信息
   * @returns ModelInfo | null 模型信息对象
   */
  getModelInfo(): ModelInfo | null;

  /**
   * 离线渲染模型（不可使用 ASR、TTS、咨询大模型等功能）
   * @param files 模型文件列表
   * @returns Promise<boolean> 是否成功
   */
  offlineRender(files: CharacterModel[]): Promise<boolean>;

  // ========== 对话功能 ==========

  /**
   * AI 流式问答
   * @param params 问答参数
   * @param callback 回调函数
   * @returns Promise<Result<AskStreamResponse>> 问答响应
   */
  askStream(params: AskParams, callback: (msgs: Result<ChatMessage[]>) => void): Promise<Result<AskStreamResponse>>;

  /**
   * AI 问答（非流式）
   * @param params 问答参数
   * @param callback 回调函数
   * @returns Promise<Result<AskResponse>> 问答响应
   */
  ask(params: AskParams, callback: AskCallback): Promise<Result<AskResponse>>;

  /**
   * 文本播报
   * @param text 播报文本
   * @param callback 可选的回调函数
   * @returns Promise<StreamAudioPlayInfo> 播放信息
   */
  speak(text: string, callback?: SpeakCallback): Promise<StreamAudioPlayInfo>;

  /**
   * 停止当前播报和动作
   * @returns Promise<boolean> 是否成功
   */
  stop(): Promise<boolean>;

  /**
   * 使用音频和 BlendShapes 播报
   * @param uris 音频 URL 列表
   * @param shapes BlendShapes 数据列表
   * @returns Promise<boolean> 是否成功
   */
  speakByAudioShapes(uris: string[], shapes: Array<number[][]>): Promise<boolean>;

  // ========== 音频控制 ==========

  /**
   * 音频静音控制
   * @param isMute true: 静音，false: 取消静音
   */
  muteAudio(isMute: boolean): void;

  /**
   * 动作禁用控制
   * @param isMute true: 禁用，false: 取消禁用
   */
  muteAction(isMute: boolean): void;

  // ========== 语音交互 ==========

  /**
   * 开始语音转文本
   * @param callback 可选的回调函数
   * @returns Promise<Result<RecorderPermission>> 录音权限结果
   */
  startVoice2Text(callback?: Voice2TextCallback): Promise<Result<RecorderPermission>>;

  /**
   * 停止语音转文本
   * @param callback 可选的回调函数
   * @returns Promise<Result<null>> 结果
   */
  stopVoice2Text(callback?: Voice2TextCallback): Promise<Result<null>>;

  /**
   * 打开语音交互模式
   * @param config 语音配置
   * @returns Promise<boolean> 是否成功
   */
  openVoiceInteraction(config: VoiceConfig): Promise<boolean>;

  /**
   * 关闭录音器
   * @returns Promise<boolean> 是否成功
   */
  closeRecorder(): Promise<boolean>;

  /**
   * 打开录音器
   * @returns Promise<Result<RecorderPermission>> 录音权限结果
   */
  openRecorder(): Promise<Result<RecorderPermission>>;

  // ========== 渲染控制 ==========

  /**
   * 开始渲染
   * @returns Promise<boolean> 是否成功
   */
  startRender(): Promise<boolean>;

  /**
   * 停止渲染
   * @returns Promise<boolean> 是否成功
   */
  stopRender(): Promise<boolean>;

  /**
   * 切换视角
   * @param config 视角配置
   */
  setAngleView(config: AngleViewConfig): void;

  /**
   * 执行动画
   * @param code 动画代码
   * @param opts 播放选项
   * @returns Promise<void>
   */
  playAction(code: string, opts?: PlayActionOptions): Promise<void>;

  // ========== 摄像头功能 ==========

  /**
   * 打开摄像头
   * @param config 摄像头配置
   * @returns Promise<boolean> 是否成功
   */
  openCamera(config: CameraConfig): Promise<boolean>;

  /**
   * 开始人脸识别
   * @param config 人脸识别配置
   * @returns Promise<boolean> 是否成功
   */
  startFaceRecognition(config: FaceRecognitionConfig): Promise<boolean>;

  /**
   * 停止人脸识别
   * @returns Promise<boolean> 是否成功
   */
  stopFaceRecognition(): Promise<boolean>;

  /**
   * 开始人体检测
   * @returns Promise<boolean> 是否成功
   */
  startBodyDetect(): Promise<boolean>;

  /**
   * 停止人体检测
   * @returns Promise<boolean> 是否成功
   */
  stopBodyDetect(): Promise<boolean>;

  /**
   * 开始微笑检测
   * @param config 微笑检测配置
   * @returns Promise<boolean> 是否成功
   */
  startSmileDetection(config?: SmileDetectionConfig): Promise<boolean>;

  /**
   * 停止微笑检测
   * @returns boolean 是否成功
   */
  stopSmileDetection(): boolean;

  /**
   * 关闭摄像头并清理资源（含 DOM）
   */
  closeCamera(): void;

  // ========== 资源管理 ==========

  /**
   * 更新授权 Token
   * @param token 新的 Token
   */
  updateToken(token: string): void;

  /**
   * 销毁实例，释放所有资源
   */
  destroy(): void;
}

/**
 * Human 类构造函数参数
 */
export type HumanConstructorParams = HumanConfig;

/**
 * Human 类
 */
export interface HumanConstructor {
  new (config: HumanConfig): IHuman;
}
