/**
 * 配置相关类型定义
 * @module types/config
 */

import type { CharacterInfo, CharacterModel } from './api';
import type { Body, Camera, Light, Object3DBase, ThreeJSON } from './model';
import type { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

/**
 * 数字人角色类型
 */
export type Character = 'xiaomeng' | 'custom' | 'quan' | 'doctor' | 'boy' | 'girl' | '';

/**
 * 运行模式
 * - `normal`: 普通模式，支持所有功能
 * - `voice`: 语音交互模式（已废弃）
 * - `render-only`: 仅渲染模式，不加载交互功能
 */
export type Mode = 'normal' | 'voice' | 'render-only';

/**
 * 服务器配置
 * 用于配置 API 服务和 WebSocket 服务的地址
 */
export interface ServerConfig {
  /** 
   * API 服务地址
   * @default process.env.ROLLUP_BASE_API
   * @example 'https://console-api.qtworld.top'
   */
  api?: string;
  
  /** 
   * Gateway WebSocket 服务地址（推荐使用）
   * 统一的 WebSocket 网关，用于 LLM、TTS、ASR 功能
   * @default 'wss://qt-gateway.quantekeji.com/api/ws'
   * @example 'wss://qt-gateway.quantekeji.com/api/ws'
   */
  gateway?: string;
  
  /** 
   * 旧版 WebSocket 服务地址（将被废弃）
   * @deprecated 请使用 gateway 配置
   */
  wss?: string;
}

/**
 * 音频配置
 * 用于控制音频播放的音量和静音状态
 */
export interface AudioConfig {
  /** 
   * 音量大小，范围 0-1
   * @default 1.0
   * @example 0.8
   */
  volume?: number;
  
  /** 
   * 是否静音
   * @default false
   */
  muted?: boolean;
}

/**
 * 渲染配置
 * 用于控制 3D 渲染的性能和质量
 */
export interface RenderConfig {
  /** 
   * 渲染帧率
   * @default 30
   * @example 60
   */
  fps?: number;
  
  /** 
   * 渲染质量
   * - `low`: 低质量，性能优先
   * - `medium`: 中等质量，平衡性能和质量
   * - `high`: 高质量，质量优先
   * @default 'medium'
   */
  quality?: 'low' | 'medium' | 'high';
}

/**
 * 语音模式配置
 * @deprecated 语音交互模式已废弃
 */
export interface VoiceModeConfig {
  /** 
   * 为 true 时不会受到唤醒词、退出词和打断词的影响，程序会一直收音并且会随时打断
   * @default false
   * @deprecated
   */
  keepActive?: boolean;
}

/**
 * LLM 请求参数配置
 * 用于控制 LLM 对话生成的行为
 */
export interface QuestionApiParams {
  /**
   * LLM 模型名称
   * @default 'quan'
   */
  model?: string;
  /**
   * 最大生成 token 数
   * @default 256
   */
  max_tokens?: number;
  /**
   * 生成温度，越高越随机
   * @default 0.95
   */
  temperature?: number;
  /**
   * 是否使用流式传输
   * @default false
   */
  stream?: boolean;
  /**
   * 是否启用句级分割
   * @default true
   */
  sentence?: boolean;
  /**
   * 是否使用 SSE 推送
   * @default true
   */
  sse?: boolean;
}

/**
 * TTS 请求参数配置
 * 用于控制语音合成的行为
 */
export interface TTSApiParams {
  /**
   * 语音角色
   * @default 'xiaoxiao'
   */
  role?: string;
  /**
   * 语速倍率
   * @default 1
   */
  speed?: number;
  /**
   * TTS 序列号
   * @default 10
   */
  sn?: number;
  /**
   * TTS 模型
   * @default 'paddle2'
   */
  model?: string;
  /**
   * 口型格式
   * @default 'a2f'
   */
  viseme?: string;
  /**
   * 平滑算法
   * @default 1
   */
  smooth_method?: number;
  /**
   * 平滑迭代次数
   * 注意：字段名 interations 为后端 API 历史拼写，保持一致不做修正
   * @default 5
   */
  smooth_interations?: number;
}

/**
 * 3D 模型渲染配置
 */
export interface ModelRenderConfig {
  /**
   * 模型名称
   * @default 'quante'
   */
  name?: string;
  /** 相机配置 */
  camera?: {
    /**
     * 视场角
     * @default 50
     */
    fov?: number;
  };
  /** 轨道控制器限制 */
  orbitControls?: {
    /**
     * 最小极角（弧度）
     * @default 0
     */
    minPolarAngle?: number;
    /**
     * 最大极角（弧度）
     * @default Math.PI
     */
    maxPolarAngle?: number;
  };
}

/**
 * 加密配置
 * 用于模型加载时的 AES 解密
 */
export interface CryptoConfig {
  /** AES 加密盐值 */
  salt?: string;
  /** AES 初始化向量 */
  iv?: string;
}

/**
 * 语音交互配置
 * 用于配置 WebRTC 语音交互模式
 */
export interface VoiceConfig {
  /**
   * 唤醒词列表
   * 当识别到这些词时，进入激活状态开始对话
   * @example ['你好', '你好小全']
   */
  wakeWords?: string[];

  /**
   * 退出词列表（休眠）
   * 当识别到这些词时，退出激活状态进入休眠
   * @example ['关闭', '退出']
   */
  exitWords?: string[];

  /**
   * 打断词列表
   * 当识别到这些词时，打断当前播放
   * @example ['停止', 'stop', '返回']
   */
  interruptWords?: string[];

  /**
   * 音频采样率
   * @default 16000
   */
  sampleRate?: number;

  /**
   * 无操作时退出时间（毫秒）
   * 激活状态下无操作超过此时间后自动进入休眠
   * @default 30000
   */
  exitTime?: number;

  /**
   * 是否保持常开模式
   * 为 true 时不受唤醒词、退出词影响，始终处于激活状态
   * @default false
   */
  keepActive?: boolean;

  /**
   * 是否自动开始对话
   * 为 true 时识别到语音后自动发送给 LLM
   * @default true
   */
  autoAsk?: boolean;

  /**
   * 静音检测时间（毫秒）
   * 用户停止说话后等待此时间确认语音结束
   * @default 1500
   */
  silenceTimeout?: number;

  /**
   * 是否启用 A2F 口型
   * @default true
   */
  a2fEnabled?: boolean;

  /** 是否要求唤醒词说两遍（如"小德小德"），默认 false（向后兼容） */
  doubleWakeWord?: boolean

  /** 唤醒确认语，如"在呢"。唤醒后通过直接 TTS 播报（不走 LLM，不入历史） */
  wakeConfirmText?: string

  /** 额外 synthetic 白名单文本（如工具确认语），通过 CMD 1031 下发给 Gateway 做会话级校验 */
  syntheticTexts?: string[]

  /** 连续对话窗口时长（ms），TTS 结束后保持监听，默认使用 exitTime */
  continuousWindowMs?: number

  /** 优雅退出提示语，如"还有什么要问的吗？"。通过直接 TTS 播报 */
  gracefulExitPrompt?: string

  /** 是否启用优雅退出（先提示再休眠），默认 false */
  gracefulExitEnabled?: boolean

  /** 严格打断模式：TTS 播放中仅角色名可打断（排除 interruptWords），默认 false */
  bargeInStrictMode?: boolean

  // ─── 高级调优参数 ───

  /**
   * 打断冷却时间（毫秒）
   * @default 500
   */
  bargeInCooldownMs?: number;

  /**
   * LLM 请求超时（毫秒）
   * @default 30000
   */
  llmTimeoutMs?: number;

  /**
   * LLM 最大重试次数
   * @default 2
   */
  llmMaxRetry?: number;

  /**
   * WebRTC 重连间隔（毫秒）
   * @default 3000
   */
  webrtcReconnectInterval?: number;

  /**
   * WebRTC 最大重连次数
   * @default 3
   */
  webrtcMaxReconnectAttempts?: number;

  /**
   * VAD 触发窗口（毫秒），唤醒后在此窗口内 VAD 处于门控状态
   * @default 2500
   */
  vadGateWindowMs?: number;

  /**
   * VAD 宽限期（毫秒），TTS 播放结束后的 VAD 静默宽限
   * @default 4000
   */
  vadGraceMs?: number;

  /**
   * 打断后跟进窗口（毫秒），打断后保持监听的时间
   * @default 6000
   */
  interruptFollowUpWindowMs?: number;

  /**
   * 优雅退出 Phase2 提示语
   * @default '如果没有其他问题，我先休息了哦'
   */
  gracefulExitPhase2Prompt?: string;

  /**
   * 优雅退出 Phase2 静默时间（毫秒）
   * @default 60000
   */
  gracefulExitPhase2Silence?: number;

  /**
   * 优雅退出 Phase3 静默时间（毫秒）
   * @default 30000
   */
  gracefulExitPhase3Silence?: number;

  /**
   * 打断词过滤窗口（毫秒），唤醒后在此窗口内过滤打断词
   * @default 3000
   */
  interruptWordFilterMs?: number;

  /**
   * 欢迎语后 ASR 恢复延迟（毫秒）
   * @default 1200
   */
  welcomeAsrResumeDelayMs?: number;

  /**
   * 语音提问超时（毫秒），由 Human 编排层消费（非 VoiceConversation）
   * 仅在使用 Human.openVoiceInteraction() 旧版语音模式时生效
   * @default 120000
   */
  voiceAskTimeout?: number;

  /**
   * TTS 播放安全超时（毫秒），由 Human 编排层消费（非 VoiceConversation）
   * 超时后强制结束播放，防止 isTTSPlaying 状态卡住
   * @default 30000
   */
  ttsSafetyTimeoutMs?: number;
}

/**
 * Human 初始化配置
 * 用于创建数字人实例时的配置选项
 * 
 * @example
 * ```typescript
 * const config: HumanConfig = {
 *   token: 'your-auth-token',
 *   container: 'human-container',
 *   characterId: 'your-character-id',
 *   audio: {
 *     volume: 0.8,
 *     muted: false
 *   },
 *   render: {
 *     fps: 60,
 *     quality: 'high'
 *   }
 * }
 * 
 * const human = new Human(config)
 * ```
 */
export interface HumanConfig {
  /** 
   * 授权 Token（必填）
   * 从 qtworld 平台获取的授权令牌
   * @see https://console.quantekeji.com/login
   */
  token: string;
  
  /** 
   * 渲染容器
   * 可以是 DOM 元素的 ID 字符串或 HTMLElement 对象
   * 如果不提供，则只加载模型不渲染
   * @example 'human-container'
   * @example document.getElementById('container')
   */
  container?: string | HTMLElement;
  
  /** 
   * 数字人 ID
   * 从 qtworld 平台获取的数字人标识
   * @example 'character-123456'
   */
  characterId?: string;
  
  /**
   * 服务配置
   * 配置 API 服务和 WebSocket 服务的地址
   */
  server?: ServerConfig;

  /**
   * iOS 音频实验模式
   * - `baseline`: 保持当前线上行为（禁用浏览器 AEC）
   * - `aec`: 启用 echoCancellation/noiseSuppression，AGC 关闭
   * - `aec_full`: 启用 echoCancellation/noiseSuppression/AGC
   * @default 'baseline'
   */
  iosAudioMode?: 'baseline' | 'aec' | 'aec_full';
  
  /** 
   * 音频配置
   * 控制音频播放的音量和静音状态
   */
  audio?: AudioConfig;
  
  /** 
   * 渲染配置
   * 控制 3D 渲染的性能和质量
   */
  render?: RenderConfig;
  
  /** 
   * 运行模式
   * - `normal`: 普通模式（默认）
   * - `voice`: 语音交互模式（已废弃）
   * - `render-only`: 仅渲染模式
   * @default 'normal'
   */
  mode?: Mode;
  
  /** 
   * 语音模式配置
   * @deprecated 语音交互模式已废弃
   */
  voiceModeConfig?: VoiceModeConfig;
  
  /** 
   * 加载动画元素
   * 可以是 DOM 元素的 ID 字符串或 HTMLElement 对象
   * 用于显示加载进度
   * @example 'loading-container'
   */
  loading?: string | HTMLElement;
  
  /** 
   * 加载完成后是否销毁加载动画
   * @default true
   */
  loadingDestroy?: boolean;
  
  /** 
   * 是否立即渲染
   * 为 true 时不会自动开始渲染，需要手动调用 startRender()
   * @default false
   */
  isNotRender?: boolean;
  
  /** 
   * 调试模式
   * 开启后会输出更多日志信息
   * @default false
   */
  debug?: boolean;
  
  /**
   * 3D 模型渲染配置
   * 控制相机视角和轨道控制器行为
   */
  modelConfig?: ModelRenderConfig;

  /**
   * LLM 请求参数
   * 控制对话生成的模型、温度、token 限制等
   */
  questionApiParams?: QuestionApiParams;

  /**
   * TTS 语音合成参数
   * 控制语音角色、语速、口型格式等
   */
  text2SpeachApiParams?: TTSApiParams;

  /**
   * 加密配置
   * 用于模型加载时的 AES 解密，不传则使用内置默认值
   */
  crypto?: CryptoConfig;
  
  /** 
   * 其他配置选项
   */
  options?: {
    /** 
     * BlendShapes 每秒执行的帧数
     * 控制面部表情和口型动画的流畅度
     * @default 30
     * @example 60
     */
    fps?: number;
  };
}

/**
 * 相机视角配置
 * 用于控制 3D 场景的相机位置和角度
 * 
 * @example
 * ```typescript
 * // 切换到正面视角
 * human.setAngleView({
 *   camera: {
 *     position: [0, 1.6, 2],
 *     fov: 50,
 *     duration: 1000  // 1秒过渡动画
 *   }
 * })
 * ```
 */
export interface AngleViewConfig {
  /** 
   * 相机配置
   */
  camera?: {
    /** 
     * 相机位置 [x, y, z]
     * @example [0, 1.6, 2]
     */
    position?: [number, number, number];
    
    /** 
     * 相机旋转角度 [x, y, z]（弧度）
     * @example [0, 0, 0]
     */
    rotation?: [number, number, number];
    
    /** 
     * 视场角（Field of View）
     * @default 50
     * @example 60
     */
    fov?: number;
    
    /** 
     * 动画持续时间（毫秒）
     * 设置相机移动的过渡动画时长
     * @default 0
     * @example 1000
     */
    duration?: number;
  };
  
  /** 
   * 轨道控制器配置
   */
  controls?: {
    /** 
     * 控制器目标点 [x, y, z]
     * 相机围绕此点旋转
     * @example [0, 1, 0]
     */
    target?: [number, number, number];
    
    /** 
     * 是否启用轨道控制器
     * @default true
     */
    enabled?: boolean;
    
    /** 
     * 动画持续时间（毫秒）
     * @default 0
     * @example 1000
     */
    duration?: number;
  };
}

/**
 * 运行时内部使用的渲染配置。
 * 该结构保持后台协议的输入边界稳定，同时为后续 runtime 拆分提供明确的中间层。
 */
export interface ResolvedRenderConfig {
  name?: string;
  scene?: Object3DBase;
  camera?: ThreeJSON<Camera>;
  orbitControls?: ThreeJSON<OrbitControls>;
  lights: ThreeJSON<Light>[];
  model?: Object3DBase & { body: Body; rotate?: boolean };
  gridHelper?: {
    size?: number;
    divisions?: number;
    color1?: string | number;
    color2?: string | number;
  };
  dracoPath?: string;
}

/**
 * 角色资源侧配置。
 * 保留后台当前真实下发的 scene 结构，避免阶段 0 就丢失 glb/video/picture/background 分支信息。
 */
export interface ResolvedAssetSceneConfig extends Partial<NonNullable<CharacterInfo['scene']>> {
  id?: string;
  name?: string;
  type?: string;
  path?: string;
  pictures?: string[];
  background?: unknown;
}

export interface ResolvedAssetConfig {
  aposes: CharacterModel[];
  animations: CharacterModel[];
  scene: ResolvedAssetSceneConfig | null;
}

export interface ResolvedBehaviorConfig {
  animationEnabled: boolean;
  debug: boolean;
  isNotRender: boolean;
}

export interface ResolvedCharacterConfig {
  render: ResolvedRenderConfig;
  assets: ResolvedAssetConfig;
  behavior: ResolvedBehaviorConfig;
}
