import Foundation

/// 「导出身体档案」用到的两个 LLM prompt:
/// 1. `intentExtraction` —— 抽取时间窗 + 指标/症状关键词,只输出 JSON
/// 2. `reportGeneration` —— 拼真实数据后生成给医生看的 Markdown
///
/// 解析逻辑见 `HealthExportService`(§3.2 失败回退红线:
/// 抽不出 JSON → 用 30 天 + 空关键词兜底,流程不中断)。
enum HealthExportPrompts {

    // MARK: - 意图抽取

    /// `intentExtraction(userPrompt:)` 把用户原话拼到模板末尾。
    /// 期望输出形如:
    /// ```json
    /// {"time_range_days":30,
    ///  "keywords":["体温","血压"],
    ///  "symptom_keywords":["感冒","咳嗽"],
    ///  "intent":"cold_consult",
    ///  "intent_label_cn":"感冒就诊"}
    /// ```
    static func intentExtraction(userPrompt: String) -> String {
        """
        你是健康数据助手。读用户的请求,只输出严格 JSON,不要解释、不要 markdown 围栏、不要任何前后缀文字。

        字段说明(全部必填):
        {
          "time_range_days": int,         // 回溯天数,默认 30,最大 365
          "keywords": [string],            // 指标关键词(中文,如「血压」「血糖」「体温」「肝功」),无则 []
          "symptom_keywords": [string],    // 症状关键词,无则 []
          "intent": string,                // 英文 snake_case 标签,如 "cold_consult"
          "intent_label_cn": string        // 中文短语,会作为报告标题副题,如 "感冒就诊"
        }

        规则:
        - 时间未指定 → 30
        - 「最近一个月」→ 30,「最近三个月」→ 90,「最近半年」→ 180
        - 关键词要中文,常见健康指标 / 症状词
        - intent 简短,4-25 字符,小写下划线

        示例 1:
        User: 我感冒3天了,要把最近一个月的健康情况给医生看
        Output: {"time_range_days":30,"keywords":["体温","血压","脉搏"],"symptom_keywords":["感冒","咳嗽","咽喉痛","发烧"],"intent":"cold_consult","intent_label_cn":"感冒就诊"}

        示例 2:
        User: 我最近血糖好像不稳,把上次体检前后的化验单整理一下
        Output: {"time_range_days":90,"keywords":["血糖","糖化血红蛋白","胰岛素"],"symptom_keywords":[],"intent":"glucose_review","intent_label_cn":"血糖复查"}

        现在请输出 JSON:
        User: \(userPrompt)
        Output: /no_think
        """
    }

    // MARK: - 报告生成

    /// `reportGeneration(userPrompt:intentLabelCN:dataJSON:)` 拼好后流式生成 Markdown。
    static func reportGeneration(userPrompt: String,
                                 intentLabelCN: String,
                                 dataJSON: String) -> String {
        let labelLine = intentLabelCN.isEmpty
            ? "# 就诊摘要"
            : "# 就诊摘要 — \(intentLabelCN)"
        return """
        你是健康数据整理员。任务是把下面【真实数据】(JSON)里**已经存在**的内容,
        原样整理成一份给社区医生看的就诊摘要。这是**抽取 / 搬运**任务,不是创作。

        【最重要的铁律 —— 违反即失败】
        - 只能使用【真实数据】JSON 里**真实出现过**的内容。
        - 严禁编造或推测任何数字、日期、症状、药物、检查结果、诊断,哪怕看起来很合理。
        - JSON 里没有的信息,对应小节一律写「无记录」,不要补全、不要举例、不要套用常见病例模板。
        - 数值必须原样照搬(含单位与参考范围);status 为 high/low/abnormal 的指标前加 ⚠️。
        - 「主诉」「本人疑问」可参考【本人原话】,但不得加入原话与数据里都没有的症状。

        输出格式:
        - 严格 Markdown,标题用 # / ##,不要 markdown 围栏,不要输出 JSON,不写「数据」二字。
        - 不给诊断意见、用药建议或「建议就医」。全文中文,简洁,医生 30 秒能扫完。
        - 严格按以下 6 段(顺序与标题固定):
        \(labelLine)
        ## 主诉
        ## 本人背景
        ## 近期症状(按时间倒序)
        ## 关键指标(异常项优先)
        ## 在服药与过敏
        ## 本人疑问

        —— 格式示例(只示范「无记录」与数值写法,内容请勿照抄)——
        真实数据:{"profile":{},"symptoms":[],"indicators":[{"name":"体温","value":"38.5","unit":"℃","range":"36-37.2","status":"high","date":"2026-05-01"}],"reports":[],"diaries":[],"time_window":{"from":"2026-04-02","to":"2026-05-02"}}
        输出:
        # 就诊摘要 — 近期健康摘要
        ## 主诉
        无记录
        ## 本人背景
        无记录
        ## 近期症状(按时间倒序)
        无记录
        ## 关键指标(异常项优先)
        ⚠️ 体温 38.5 ℃(参考 36-37.2,2026-05-01)
        ## 在服药与过敏
        无记录
        ## 本人疑问
        无记录
        —— 示例结束(以上咳嗽/体温等仅示范格式,切勿出现在你的输出里)——

        现在,严格根据下面这份【真实数据】生成;数据里没有的就写「无记录」,**禁止编造**:

        【真实数据】:
        \(dataJSON)

        【本人原话】:\(userPrompt)

        再次强调:只整理上面【真实数据】里真实出现过的内容,禁止编造任何数字/日期/症状/药物。
        直接输出 Markdown,不要思考过程,不要 <think> 标签:
        /no_think
        """
    }

    // MARK: - 多轮导出对话

    /// 多轮导出页里,用户每次提问时用这个 prompt 回答。
    /// 输入上下文限定为本地指标 + 健康日记,回答只做解释/归纳,不持久化。
    static func dialogueAnswer(latestQuestion: String,
                               transcript: String,
                               dataJSON: String) -> String {
        """
        你是康康的本地健康档案助手。请根据【本地健康记录】回答用户最新问题。

        铁律:
        - 只能使用【本地健康记录】和【多轮对话】里已有的信息。
        - 禁止诊断、禁止用药/剂量建议、禁止急诊判断。
        - 数据里没有的信息,直接说「记录里没有」,不要编造。
        - 重点围绕指标和健康日记做大白话解释,回答要短,最多 5 条要点。
        - 如果用户的目标是给医生看,可以提示稍后点击「生成整理报告」。

        【本地健康记录】:
        \(dataJSON)

        【多轮对话】:
        \(transcript.isEmpty ? "无" : transcript)

        【用户最新问题】:
        \(latestQuestion)

        直接输出中文回答,不要 Markdown 标题,不要 <think>:
        /no_think
        """
    }

    /// 对话结束后,把整段交流整理成一份给医生看的 Markdown 报告。
    static func dialogueReportGeneration(transcript: String,
                                         dataJSON: String) -> String {
        """
        你是健康数据整理员。请把【多轮对话】和【本地健康记录】整理成一份给医生看的摘要报告。
        这是抽取 / 搬运任务,不是医疗诊断。

        铁律:
        - 只能使用【本地健康记录】和【多轮对话】里真实出现的信息。
        - 禁止编造数字、日期、症状、药物、检查结果、诊断。
        - 日期一律照搬【本地健康记录】JSON 里的完整 `date` 字段(格式 yyyy-MM-dd,即年-月-日);严禁只写年份或省略月、日。多轮对话里若把日期说得不全,一律以 JSON 的完整日期为准。
        - 禁止给诊断意见、用药建议、剂量建议或急诊判断。
        - JSON 里没有的信息,对应小节写「无记录」。
        - 指标 status 为 high/low/abnormal 的项目前加 ⚠️。

        输出要求:
        - 严格 Markdown,不要 markdown 围栏,不要输出 JSON。
        - 中文,简洁,医生 30 秒能扫完。
        - 「相关健康日记」每条单独一行,格式为「2026-05-01:正文摘要」,日期照抄 JSON 的 date 字段,精确到日。
        - 严格按以下段落:
        # 就诊摘要
        ## 本次想解决的问题
        ## 相关健康日记
        ## 相关指标
        ## 已知背景
        ## 本人关心的问题
        ## 可带给医生确认的要点

        【本地健康记录】:
        \(dataJSON)

        【多轮对话】:
        \(transcript.isEmpty ? "无" : transcript)

        直接输出 Markdown,不要思考过程,不要 <think>:
        /no_think
        """
    }
}
