package com.lila.wakeup

import android.media.AudioFormat

/**
 * KWS APK 全局配置常量。
 *
 * 协议版本：v2.1（详见 KWS唤醒协议-V2.md）
 * 涵盖三类常量：
 *  - 协议常量（Action 名、对端包名、字段键）
 *  - 引擎参数（阈值、平滑、超时、采样率）
 *  - 模型路径（assets 内相对路径）
 */
object Config {

    // ============================================================
    // 一、协议常量
    // ============================================================

    /** 本 APK 包名（自身） */
    const val SELF_PACKAGE = "com.lila.wakeup"

    /** 数字人 APP 包名（已确认 v2.1） */
    const val APP_PACKAGE = "com.qy.lila"

    /** 唤醒事件广播 Action（本 → APP） */
    const val ACTION_WAKEUP = "com.lila.intent.action.WAKEUP"

    /** 暂停 KWS 广播 Action（APP → 本） */
    const val ACTION_KWS_PAUSE = "com.lila.intent.action.KWS_PAUSE"

    /** 恢复 KWS 广播 Action（APP → 本） */
    const val ACTION_KWS_RESUME = "com.lila.intent.action.KWS_RESUME"

    /** WAKEUP Extras: 命中的唤醒词文本 */
    const val EXTRA_KEYWORD = "keyword"

    /** WAKEUP Extras: 命中时间戳（毫秒） */
    const val EXTRA_TIMESTAMP = "timestamp"

    /** WAKEUP Extras: 置信度 [0,1] */
    const val EXTRA_CONFIDENCE = "confidence"

    /** PAUSE Extras: 静默期毫秒数 */
    const val EXTRA_SILENCE_MS = "silence_ms"

    /** PAUSE/RESUME Extras: 调用原因（透传日志） */
    const val EXTRA_REASON = "reason"

    /**
     * 内部广播 Action（仅本 APP 自己接收,用于 MainActivity UI 实时显示命中）。
     * 与对外协议 [ACTION_WAKEUP] 隔离,避免外部 APP 干扰内部 UI 状态。
     */
    const val ACTION_INTERNAL_WAKEUP = "com.lila.wakeup.action.INTERNAL_WAKEUP"

    // ============================================================
    // 二、引擎参数
    // ============================================================

    /** PAUSE 默认静默期（v2.1 微调：3000ms 覆盖 RTC 远端音频回灌 + AI TTS 触发延迟） */
    const val DEFAULT_SILENCE_MS = 3000L

    /** APP 漏发 RESUME 时的兜底超时（2 分钟） */
    const val PAUSE_TIMEOUT_MS = 2 * 60 * 1000L

    // 注:KWS_THRESHOLD / SMOOTH_FRAMES 已移除,使用 sherpa-onnx 默认值
    //   - keywordsThreshold 默认 0.25 (KeywordSpotterConfig)
    //   - 不做外部后验平滑(sherpa-onnx 内部 numTrailingBlanks 已平滑)
    //   原因见 KwsEngine.kt / KwsStateMachine.kt 注释

    // ============================================================
    // 三、AudioRecord 配置
    // ============================================================

    /** 采样率（sherpa-onnx 模型固定 16kHz） */
    const val SAMPLE_RATE = 16_000

    /** 单声道 */
    const val CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO

    /** 16-bit PCM */
    const val ENCODING = AudioFormat.ENCODING_PCM_16BIT

    /**
     * 单帧采样点数(100ms 帧 @ 16kHz = 1600 samples)。
     *
     * ⚠️ 必须与 sherpa-onnx 官方 demo 一致(用 100ms 帧)。
     * 之前用 10ms 帧(160 sample)第一次能识别,之后再无命中——sherpa-onnx
     * 内部 chunk 累积/边界处理对小帧不友好。改用 100ms 后稳定。
     */
    const val FRAME_SAMPLES = SAMPLE_RATE / 10

    // ============================================================
    // 四、模型路径（assets 内）
    // ============================================================

    /**
     * 架构演进历史:
     * - v0: KWS wenetspeech 3.3M (2024) —— 默认 keywords 命中率 30-40%
     * - v1: KWS zh-en 双语 3M —— 英文 Lila 0% 命中
     * - v2: ASR (SenseVoice 228MB) + 拼音替换 —— 板载 mic 全部 empty(模型对短词不敏感)
     * - v3: KWS Zipformer wenetspeech-3.3M + 自定义谐音 keywords.txt 流式架构(当前)
     *
     * v3 关键改动:
     *   keywords.txt 用多个谐音变体覆盖("你好丽啦/咪啦/丽拉/lai啦"等)
     *   流式实时识别,不再切 segment,不再依赖 VAD/能量门
     *   模型 5MB(vs SenseVoice 228MB),推理快 10x
     */
    const val KWS_MODEL_DIR = "kws"
    const val KWS_ENCODER = "kws/encoder.int8.onnx"
    const val KWS_DECODER = "kws/decoder.onnx"
    const val KWS_JOINER = "kws/joiner.int8.onnx"
    const val KWS_TOKENS = "kws/tokens.txt"
    const val KWS_KEYWORDS_FILE = "kws/keywords.txt"

    /** KWS 推理线程数 */
    const val KWS_NUM_THREADS = 2

    /**
     * 关键词命中阈值(0~1 之间),越低越容易触发。
     * 板载 mic 弱信号 + Lila 非训练词,激进降到 0.05。
     * 误触发风险:需要观察 listening 待机时是否被环境噪声误唤醒。
     */
    const val KWS_THRESHOLD = 0.05f

    /**
     * 关键词命中加分,越大越容易触发。弱信号场景拉到 3.0。
     */
    const val KWS_SCORE = 3.0f

    /**
     * AudioCapture 软件预增益(在喂 KWS 之前)。
     * 板载 mic 信号偏弱,1.5x 增益让说话峰值更接近满量程,KWS 神经网络
     * 看到的特征对比度更高。clamp 到 [-32768, 32767] 防止溢出失真。
     */
    const val AUDIO_CAPTURE_GAIN = 1.5f

    /**
     * 调试: 命中前后 dump 一段 PCM 到 WAV 文件,辅助调试。
     * 路径: /sdcard/Android/data/com.lila.wakeup/files/lila_kws/
     * 拉回: adb pull /sdcard/Android/data/com.lila.wakeup/files/lila_kws/ ./
     * 上线前关掉。
     */
    const val DUMP_HIT_WAV = true

    // ============================================================
    // 五、通知栏
    // ============================================================

    const val NOTIF_CHANNEL_ID = "lila_wakeup_kws"
    const val NOTIF_CHANNEL_NAME = "Lila 语音唤醒"
    const val NOTIF_ID = 1
}
