/**
 * ASL LLM筛选输出的JSON Schema
 * 用于验证AI模型输出格式
 */

import { JSONSchemaType } from 'ajv';
import { LLMScreeningOutput } from '../types/index.js';

export const screeningOutputSchema: JSONSchemaType<LLMScreeningOutput> = {
  type: 'object',
  properties: {
    judgment: {
      type: 'object',
      properties: {
        P: { type: 'string', enum: ['match', 'partial', 'mismatch'] },
        I: { type: 'string', enum: ['match', 'partial', 'mismatch'] },
        C: { type: 'string', enum: ['match', 'partial', 'mismatch'] },
        S: { type: 'string', enum: ['match', 'partial', 'mismatch'] },
      },
      required: ['P', 'I', 'C', 'S'],
    },
    evidence: {
      type: 'object',
      properties: {
        P: { type: 'string' },
        I: { type: 'string' },
        C: { type: 'string' },
        S: { type: 'string' },
      },
      required: ['P', 'I', 'C', 'S'],
    },
    conclusion: {
      type: 'string',
      enum: ['include', 'exclude', 'uncertain'],
    },
    confidence: {
      type: 'number',
      minimum: 0,
      maximum: 1,
    },
    reason: {
      type: 'string',
    },
  },
  required: ['judgment', 'evidence', 'conclusion', 'confidence', 'reason'],
  additionalProperties: false,
};

/**
 * 筛选风格类型
 */
export type ScreeningStyle = 'lenient' | 'standard' | 'strict';

/**
 * 生成LLM筛选的Prompt (v1.1.0 - 支持三种风格)
 * 
 * @param style - 筛选风格：
 *   - lenient: 宽松模式，宁可多纳入也不错过（适合初筛）
 *   - standard: 标准模式，平衡准确率和召回率（默认）
 *   - strict: 严格模式，宁可错杀也不放过（适合精筛）
 */
export function generateScreeningPrompt(
  title: string,
  abstract: string,
  picoCriteria: any,
  inclusionCriteria: string,
  exclusionCriteria: string,
  style: ScreeningStyle = 'standard',
  authors?: string,
  journal?: string,
  publicationYear?: number
): string {
  
  // 根据风格选择不同的Prompt基调
  const styleConfig = {
    lenient: {
      role: '你是一位经验丰富的系统综述专家，负责对医学文献进行**初步筛选（标题摘要筛选）**。',
      context: `⚠️ **重要提示**: 这是筛选流程的**第一步**，筛选后还需要下载全文进行复筛。因此：
- **宁可多纳入，也不要错过可能有价值的文献**
- **当信息不足时，倾向于"纳入"或"不确定"，而非直接排除**
- **只排除明显不符合的文献**`,
      picoGuideline: `**⭐ 宽松模式原则**:
- 只要有部分匹配，就标记为 \`partial\`，不要轻易标记为 \`mismatch\`
- 信息不足时，倾向于 \`partial\` 而非 \`mismatch\``,
      decisionRules: `**⭐ 宽松模式决策规则**:
1. **优先纳入**: 当判断不确定时，选择 \`include\` 或 \`uncertain\`，而非 \`exclude\`
2. **只排除明显不符**: 只有当文献明确不符合核心PICO标准时才排除
3. **容忍边界情况**: 对于边界情况（如地域差异、时间窗口、对照类型），倾向于纳入
4. **看潜在价值**: 即使不完全匹配，但有参考价值的也纳入

**具体容忍规则**:
- **人群地域**: 即使不是目标地域，但研究结果有参考价值 → \`include\`
- **时间窗口**: 即使不完全在时间范围内，但研究方法可参考 → \`include\`  
- **对照类型**: 即使对照不是安慰剂，但有对比意义 → \`include\`
- **研究设计**: 即使不是理想的RCT，但有科学价值 → \`include\``,
      confidenceRule: '**⭐ 宽松模式**: 置信度要求降低，0.5以上即可纳入',
      reasonExample: '虽然对照组不是安慰剂而是另一种药物，但研究方法严谨，结果有参考价值，且研究人群与目标人群有一定相似性。建议纳入全文复筛阶段进一步评估。',
      finalReminder: '**记住**: 这是**初筛**阶段，**宁可多纳入，也不要错过**。只要有任何可能的价值，就应该纳入全文复筛！'
    },
    standard: {
      role: '你是一位经验丰富的系统综述专家，负责根据PICO标准和纳排标准对医学文献进行初步筛选。',
      context: '',
      picoGuideline: '',
      decisionRules: '',
      confidenceRule: '',
      reasonExample: '具体说明你的筛选决策理由，需包含：(1)为什么纳入或排除 (2)哪些PICO标准符合或不符合 (3)是否有特殊考虑',
      finalReminder: '现在开始筛选，请严格按照JSON格式输出结果。'
    },
    strict: {
      role: '你是一位严谨的系统综述专家，负责根据PICO标准和纳排标准对医学文献进行**严格筛选**。',
      context: `⚠️ **重要提示**: 这是**严格筛选模式**，要求：
- **严格匹配PICO标准，任何维度不匹配都应排除**
- **对边界情况持保守态度**
- **优先排除而非纳入**
- **只纳入高度确定符合标准的文献**`,
      picoGuideline: `**⭐ 严格模式原则**:
- 只有**明确且完全匹配**才能标记为 \`match\`
- 任何不确定或不够明确的，标记为 \`partial\` 或 \`mismatch\`
- 对标准的理解要严格，不做宽松解释`,
      decisionRules: `**⭐ 严格模式决策规则**:
1. **一票否决**: 任何一个PICO维度为 \`mismatch\`，直接排除
2. **多个partial即排除**: 超过2个维度为 \`partial\`，也应排除
3. **触发任一排除标准**: 立即排除
4. **不确定时倾向排除**: 当信息不足无法判断时，倾向于排除
5. **要求高置信度**: 只有置信度≥0.8才纳入

**具体严格规则**:
- **人群地域**: 必须严格匹配目标地域，其他地域一律排除
- **时间窗口**: 必须严格在时间范围内，边界情况也排除
- **对照类型**: 必须是指定的对照类型（如安慰剂），其他对照排除
- **研究设计**: 必须是指定的研究设计，次优设计也排除`,
      confidenceRule: '**⭐ 严格模式**: 只有置信度≥0.8才能纳入',
      reasonExample: '虽然研究人群和干预措施匹配，但对照组为另一种药物而非安慰剂，不符合严格的对照要求。在严格筛选模式下，必须排除。',
      finalReminder: '**记住**: 这是**严格筛选**模式，**宁可错杀，不可放过**。只纳入**完全确定符合**所有标准的高质量文献！'
    }
  };

  const config = styleConfig[style];

  return `${config.role}

${config.context}

## 研究方案信息

**PICO标准：**
- **P (研究人群)**: ${picoCriteria.population}
- **I (干预措施)**: ${picoCriteria.intervention}
- **C (对照)**: ${picoCriteria.comparison}
- **O (结局指标)**: ${picoCriteria.outcome}
- **S (研究设计)**: ${picoCriteria.studyDesign}

**纳入标准：**
${inclusionCriteria}

**排除标准：**
${exclusionCriteria}

---

## 待筛选文献

**标题：** ${title}

**摘要：** ${abstract}

${authors ? `**作者：** ${authors}` : ''}
${journal ? `**期刊：** ${journal}` : ''}
${publicationYear ? `**年份：** ${publicationYear}` : ''}

---

## 筛选任务

请按照以下步骤进行筛选：

### 步骤1: PICO逐项评估

对文献的每个PICO维度进行评估，判断是否匹配：
- **match** (匹配)：文献明确符合该标准
- **partial** (部分匹配)：文献部分符合，或表述不够明确
- **mismatch** (不匹配)：文献明确不符合该标准

${config.picoGuideline}

### 步骤2: 提取证据

从标题和摘要中提取支持你判断的**原文片段**，每个维度给出具体证据。

### 步骤3: 综合决策

基于PICO评估、纳排标准，给出最终筛选决策：
- **include** (纳入)：文献符合所有或大部分PICO标准，且满足纳入标准
- **exclude** (排除)：文献明确不符合PICO标准，或触发排除标准
- **uncertain** (不确定)：信息不足，无法做出明确判断

${config.decisionRules}

### 步骤4: 置信度评分

给出你对此判断的把握程度（0-1之间）：
- **0.9-1.0**: 非常确定，有充分证据支持
- **0.7-0.9**: 比较确定，证据较为充分
- **0.5-0.7**: 中等把握，证据有限
- **0.0-0.5**: 不确定，信息严重不足

${config.confidenceRule}

---

## 输出格式要求

请**严格按照**以下JSON格式输出，不要添加任何额外文字：

⚠️ **重要**: 必须使用ASCII引号（"），不要使用中文引号（""）

\`\`\`json
{
  "judgment": {
    "P": "match",
    "I": "match", 
    "C": "partial",
    "S": "match"
  },
  "evidence": {
    "P": "从摘要中引用支持P判断的原文",
    "I": "从摘要中引用支持I判断的原文",
    "C": "从摘要中引用支持C判断的原文",
    "S": "从摘要中引用支持S判断的原文"
  },
  "conclusion": "include",
  "confidence": 0.85,
  "reason": "${config.reasonExample}"
}
\`\`\`

## 关键约束

1. **judgment** 的每个字段只能是：\`"match"\`, \`"partial"\`, \`"mismatch"\`
2. **evidence** 必须引用原文，不要编造内容
3. **conclusion** 只能是：\`"include"\`, \`"exclude"\`, \`"uncertain"\`
4. **confidence** 必须是0-1之间的数字
5. **reason** 长度在50-300字之间，说理充分
6. 输出必须是合法的JSON格式

## 医学文献筛选原则

- 优先考虑研究设计的严谨性（RCT > 队列研究 > 病例对照）
- 标题和摘要信息不足时，倾向于 \`"uncertain"\` 而非直接排除
- 对于综述、系统评价、Meta分析，通常排除（除非方案特别说明）
- 动物实验、体外实验通常排除（除非方案特别说明）
- 会议摘要、病例报告通常排除
- 注意区分干预措施的具体类型（如药物剂量、手术方式）
- 结局指标要与方案一致（主要结局 vs 次要结局）

---

${config.finalReminder}
`;
}

