import Testing
import Foundation
@testable import 康康

/// 语音直达的两个纯函数:LLM 输出解析 + 关键词回退。
struct VoiceIntentServiceTests {

    // MARK: - parseIntent(LLM 输出容错)

    @Test func parsesStandardJSON() {
        #expect(VoiceIntentService.parseIntent(from: #"{"intent":"indicator"}"#) == .indicator)
    }

    @Test func parsesFencedAndThinkWrapped() {
        let raw = """
        <think>用户想记血压</think>
        ```json
        {"intent": "Indicator"}
        ```
        """
        #expect(VoiceIntentService.parseIntent(from: raw) == .indicator)
    }

    @Test func parsesBareWord() {
        #expect(VoiceIntentService.parseIntent(from: "symptom") == .symptom)
        #expect(VoiceIntentService.parseIntent(from: "\"diary\"。") == .diary)
    }

    @Test func unknownReturnsNil() {
        #expect(VoiceIntentService.parseIntent(from: #"{"intent":"unknown"}"#) == nil)
        #expect(VoiceIntentService.parseIntent(from: "我不知道") == nil)
    }

    // MARK: - keywordMatch(回退规则与优先级)

    @Test func reminderBeatsMedication() {
        // 「提醒我吃药」是设提醒,不是记用药 —— reminder 规则必须排最前
        #expect(VoiceIntentService.keywordMatch("每天八点提醒我吃药") == .reminder)
    }

    @Test func commonUtterances() {
        #expect(VoiceIntentService.keywordMatch("记一下血压,高压128") == .indicator)
        #expect(VoiceIntentService.keywordMatch("我有点头疼") == .symptom)
        #expect(VoiceIntentService.keywordMatch("拍个药盒") == .medication)
        #expect(VoiceIntentService.keywordMatch("把体检报告存进去") == .archive)
        #expect(VoiceIntentService.keywordMatch("整理一份给医生看的") == .export)
        #expect(VoiceIntentService.keywordMatch("写个日记") == .diary)
    }

    @Test func unmatchedDefaultsToDiary() {
        // 不明确命中其它意图时,兜底进日记(最常见、最自由的入口)
        #expect(VoiceIntentService.keywordMatch("啦啦啦啦") == .diary)
        #expect(VoiceIntentService.keywordMatch("今天感觉不太舒服") == .diary)
        #expect(VoiceIntentService.keywordMatch("有点难受") == .diary)
    }

    // MARK: - 相机类意图的误开防护(本次修复重点)

    @Test func negatedMedicationDoesNotOpenCamera() {
        // 「没吃药 / 忘了吃药 / 不用吃药」不该归 medication(会弹拍药盒相机),落 diary
        #expect(VoiceIntentService.keywordMatch("今天太忙,忘了吃药") == .diary)
        #expect(VoiceIntentService.keywordMatch("我今天没吃药") == .diary)
        #expect(VoiceIntentService.keywordMatch("医生说先不用吃药") == .diary)
    }

    @Test func casualReportMentionDoesNotOpenCamera() {
        // 顺口提到体检/报告,不是要拍报告归档,不该弹文档相机
        #expect(VoiceIntentService.keywordMatch("下周打算去做个体检") == .diary)
        #expect(VoiceIntentService.keywordMatch("医生说我报告没什么大问题") == .diary)
    }

    @Test func genuineCameraIntentsStillMatch() {
        // 真实的拍药盒 / 归档意图仍要正确命中
        #expect(VoiceIntentService.keywordMatch("拍个药盒") == .medication)
        #expect(VoiceIntentService.keywordMatch("我吃了降压药,记一下") == .medication)
        #expect(VoiceIntentService.keywordMatch("把体检报告存进去") == .archive)
        #expect(VoiceIntentService.keywordMatch("这张化验单归档") == .archive)
    }
}
