from typing import Dict
from agent_system.base import BaseAgent
from agent_system.monitor.prompt import MonitorPrompt
from agent_system.monitor.response_model import MonitorResult

class Monitor(BaseAgent):
    """
    Monitor智能体
    根据具体任务提供专门的评分标准，实现分诊阶段和病史收集阶段的精准评估
    """
    
    def __init__(self, model_type: str = "gpt-oss:latest", llm_config: dict = {}):
        super().__init__(
            model_type=model_type,
            description=MonitorPrompt.description,
            instructions=MonitorPrompt.instructions,
            response_model=MonitorResult,
            llm_config=llm_config,
            structured_outputs=True,
            markdown=False,
            use_cache=False
        )
    
    def run(self, hpi_content: str, ph_content: str, chief_complaint: str, 
            task_name: str = None, task_description: str = None,
            triage_result: dict = None) -> MonitorResult:
        """
        监控病史质量
        
        Args:
            hpi_content: 现病史内容
            ph_content: 既往史内容  
            chief_complaint: 主诉
            task_name: 任务名称（可选，用于针对性评估）
            task_description: 任务描述（可选，用于针对性评估）
            triage_result: 分诊结果（可选，仅在分诊阶段使用）
            
        Returns:
            MonitorResult: 包含完成度评分和评分理由
        """
        if task_name and task_description:
            prompt = self._build_task_specific_prompt(task_name, task_description, 
                                                    hpi_content, ph_content, chief_complaint,
                                                    triage_result)
        else:
            prompt = self.build_prompt(hpi_content, ph_content, chief_complaint, triage_result)
        
        # 调用LLM进行评估
        result = super().run(prompt)
        
        # 确保返回正确的类型
        if isinstance(result, MonitorResult):
            return result
        elif isinstance(result, dict):
            return MonitorResult(**result)
        else:
            return MonitorResult(
                completion_score=0.0,
                reason="监控评估失败：无法解析LLM响应"
            )
    
    def build_prompt(self, hpi_content: str, ph_content: str, chief_complaint: str,
                    triage_result: dict = None) -> str:
        """
        构建整体病史质量评估的提示语
        
        Args:
            hpi_content: 现病史内容
            ph_content: 既往史内容
            chief_complaint: 主诉
            triage_result: 分诊结果（可选）
            
        Returns:
            str: 构建好的提示语
        """
        task_name = "整体病史质量评估"
        task_description = "综合评估现病史、既往史和主诉的信息完整性"
        
        return self._build_task_specific_prompt(
            task_name, task_description, hpi_content, ph_content, chief_complaint, triage_result
        )
    
    def _build_task_specific_prompt(self, task_name: str, task_description: str,
                                  hpi_content: str, ph_content: str, chief_complaint: str,
                                  triage_result: dict = None) -> str:
        """
        构建针对特定任务的评估提示语，每个子任务有专门的评分标准
        
        Args:
            task_name: 任务名称
            task_description: 任务描述
            hpi_content: 现病史内容
            ph_content: 既往史内容
            chief_complaint: 主诉
            triage_result: 分诊结果（可选）
            
        Returns:
            str: 构建好的任务特定评估提示语
        """
        
        # 获取任务特定的评分标准
        scoring_criteria = self._get_task_scoring_criteria(task_name, triage_result)
        
        # 构建分诊信息（仅在分诊阶段使用）
        triage_info = ""
        if task_name in ["一级科室判定", "二级科室判定"] and triage_result:
            primary_dept = triage_result.get("primary_department", "")
            secondary_dept = triage_result.get("secondary_department", "")
            triage_info = f"""
**分诊结果参考**：
一级科室：{primary_dept}
二级科室：{secondary_dept}

**评估重点**：
基于上述分诊结果，评估当前病史信息对科室选择的支持程度。"""

        prompt = f"""请对以下病史信息进行质量监控和评估：

**评估目标任务**：
任务名称：{task_name}
任务描述：{task_description}
{triage_info}

**当前病史信息**：
主诉：{chief_complaint}

**现病史**：
{hpi_content}

**既往史**：
{ph_content}

**评估要求**：
1. **专门针对任务"{task_name}"进行评估**
2. 根据任务描述"{task_description}"，判断当前病史信息在这个方面的完整性
3. 重点关注与该任务相关的信息是否充分收集
4. 基于临床实际价值进行评估，否定性回答（如"无""未发生""不记得"）具有同等重要的临床意义
5. 考虑记忆限制的合理性，对时间久远或非关键细节接受模糊回答
6. 避免过度询问，当患者明确表示无相关情况时不应继续追问
7. 给出该任务的完成度评分（0.0-1.0范围）
8. 详细说明评分理由，解释信息缺失是否影响诊疗决策

{scoring_criteria}

**临床考量要点**：
- 否定性回答（如"无既往病史""无过敏史"）是重要的临床信息
- 对于时间久远的事件记不清属正常现象
- 非关键性细节（如具体药物商品名）的模糊回答不影响评分
- 重点关注与当前病情密切相关的信息

**输出格式**：
严格按照以下JSON格式输出：
{{
  "completion_score": 浮点数（0.0-1.0），
  "reason": "详细评分理由，需具体说明：1)哪些信息具有临床价值（包括否定性回答）；2)哪些缺失或模糊是可接受的；3)哪些缺陷可能影响诊疗决策"
}}

请基于上述要求进行客观评估。"""
        
        return prompt
    
    def _get_task_scoring_criteria(self, task_name: str, triage_result: dict = None) -> str:
        """
        获取每个子任务专门的评分标准
        
        Args:
            task_name: 任务名称
            triage_result: 分诊结果（用于分诊阶段）
            
        Returns:
            str: 该任务的专门评分标准
        """
        
        # 分诊阶段评分标准
        if task_name == "一级科室判定":
            return """**一级科室分类评分标准**：
- 0.9-1.0：症状明确指向某一级科室，病史信息充分支持科室选择
- 0.8-0.9：症状与科室匹配度较高，病史信息基本完整，接受"可能属于某科室"等模糊判断
- 0.65-0.79：科室选择基本合理，但信息支持度一般，询问不够全面
- 0.5-0.65：科室选择勉强合理，病史信息明显不足，缺少关键信息
- 0.0-0.5：科室选择不合理或与症状描述不符，未进行基本分诊判断"""
        
        elif task_name == "二级科室判定":
            return """**二级科室分类评分标准**：
- 0.9-1.0：在一级科室基础上，症状明确指向具体二级科室，信息充分
- 0.8-0.9：二级科室选择合理，症状支持度高，信息较完整，接受"可能属于某二级科室"等模糊判断
- 0.65-0.79：二级科室选择基本合理，但信息支持度有限，询问不够全面
- 0.5-0.65：二级科室选择存疑，信息支持不足，缺少关键分诊信息
- 0.0-0.5：二级科室选择不合理或与症状不符，未进行基本二级分诊判断"""
        
        # 现病史阶段评分标准
        elif task_name == "发病情况":
            return """**发病情况评估标准**（重要：否定性诱因回答同样有效）：
- 0.85-1.0：发病时间和方式已询问，接受"突然起病""逐渐加重""无明确诱因"等回答，包括"无明显诱因""记不清具体时间"等回答视为完整
- 0.7-0.85：发病时间或方式已询问，但部分细节询问不够明确
- 0.6-0.69：发病基本情况已获取，但询问不够全面
- 0.5-0.59：缺少发病时间和方式的询问
- 0.0-0.49：发病情况询问严重缺失，未进行基本询问

**重要原则**：
- "无明显诱因""记不清具体发病时间"等回答视为有效临床信息
- 对久远事件的时间模糊回答不影响高分评价
- 重点关注发病模式是否符合当前疾病特征"""
        
        elif task_name == "主要症状特征":
            return """**主要症状特征评估标准**（重要：否定性症状描述同样有效）：
- 0.85-1.0：主要症状特征已询问，接受"疼痛程度记不清""无特殊缓解方法"等回答，包括"记不清具体部位""无明显缓解因素"等回答视为完整
- 0.7-0.85：症状基本特征已获取，但部分特征询问不够明确
- 0.6-0.69：症状特征询问已进行，但不够全面
- 0.5-0.59：缺少症状关键特征的询问
- 0.0-0.49：症状特征询问严重缺失，未进行基本询问

**重要原则**：
- "记不清具体部位""无法描述疼痛性质""无明显缓解因素"等回答视为有效临床信息
- 对症状细节记忆模糊的回答给予理解，不影响高分评价
- 重点关注症状是否符合当前疾病特征，而非描述的精确程度"""
        
        elif task_name == "病情发展与演变":
            return """**病情发展与演变评估标准**（重要：时间模糊但趋势清晰同样有效）：
- 0.9-1.0：病情演变过程按时间顺序描述，变化趋势清晰，"逐渐加重""时好时坏"等描述视为完整
- 0.8-0.89：病情发展趋势明确，接受"记不清具体时间""大概几周前开始加重"等模糊时间描述
- 0.7-0.79：病情变化基本脉络清晰，但部分时间点或变化细节略有缺失
- 0.6-0.69：病情发展大致过程可辨，时间顺序不够精确但趋势明确
- 0.5-0.59：病情变化描述不够系统，缺乏清晰的时间概念
- 0.0-0.49：病情发展信息严重缺失，无法了解疾病演变过程

**重要原则**：
- "记不清具体时间""大概几个月前"等时间模糊回答视为有效临床信息
- "逐渐加重""突然恶化""时轻时重"等趋势描述具有重要临床价值
- 对久远事件具体时间记不清属正常现象，不影响高分评价
- 重点关注病情变化趋势和规律，而非时间节点的精确性
- 慢性病程中的波动情况（如"反复发作""间歇性加重"）视为重要信息"""
        
        elif task_name == "伴随症状":
            return """**伴随症状评估标准**（重要："无伴随症状"同样具有临床价值）：
- 0.9-1.0：伴随症状已询问，包括"无其他不适""无相关症状"等否定性回答视为完整
- 0.8-0.89：主要伴随症状已询问，接受"记不清是否有其他症状""好像没有其他不适"等回答
- 0.7-0.79：伴随症状基本询问已进行，但部分相关症状询问不够明确
- 0.6-0.69：伴随症状询问已进行，但不够全面
- 0.5-0.59：缺少伴随症状的询问
- 0.0-0.49：伴随症状询问严重缺失，未进行基本询问

**重要原则**：
- "无其他症状""无伴随不适""未发现其他异常"等否定性回答视为有效完整信息
- "记不清是否有其他症状""不太确定"等模糊回答给予理解，不影响高分评价
- 重点关注与主要疾病相关的典型伴随症状，而非所有可能的症状
- 系统性疾病相关的全身症状（如发热、乏力等）询问视为重要内容"""
        
        elif task_name == "诊疗经过":
            return """**诊疗经过评估标准**（重要："未就诊""未治疗"同样具有临床价值）：
- 0.9-1.0：诊疗过程已询问，包括"未就诊""未治疗""自行缓解"等否定性回答视为完整
- 0.8-0.89：诊疗经过已询问，接受"记不清具体药物""治疗效果一般"等模糊描述
- 0.7-0.79：诊疗基本信息已获取，但部分检查或治疗细节略有缺失
- 0.6-0.69：诊疗经过基本具备，但效果描述或具体措施不够详细
- 0.5-0.59：诊疗经过信息不完整，缺乏关键诊疗信息
- 0.0-0.49：诊疗经过严重缺失，未进行基本询问

**重要原则**：
- "未就诊""未治疗""未用药"等否定性回答视为有效完整信息
- "记不清药名""记不清检查项目"等记忆模糊回答给予理解
- 重点关注诊疗措施与当前病情的相关性，而非详细的治疗记录
- 自行用药、民间疗法等信息的收集视为有价值的临床信息"""
        
        elif task_name == "一般情况":
            return """**一般情况评估标准**（重要：否定性回答具有同等临床价值）：
- 0.85-1.0：精神状态、睡眠、食欲、大小便、体重已询问，无论肯定或否定回答均视为完整
- 0.7-0.85：已询问主要生活状况，接受"无异常""正常""记不清"等回答，基本满足诊疗需求
- 0.6-0.69：基本生活状况信息已获取，但询问不够全面
- 0.5-0.59：缺少部分重要生活状况的询问
- 0.0-0.49：关键生活状况信息严重缺失，未进行基本询问

**重要原则**：
- "精神状态正常""睡眠尚可""食欲正常""大小便正常""体重无明显变化"等否定性回答视为有效信息
- 对记不清具体时间或细节的回答给予理解，不影响高分评价
- 重点关注是否存在影响诊疗的异常情况，而非描述的详细程度"""
        
        # 既往史阶段评分标准
        elif task_name == "疾病史":
            return """**疾病史评估标准**：
- 0.9-1.0：既往疾病史已询问，包括"无慢性疾病史""否认高血压糖尿病"等否定性回答视为完整有效
- 0.8-0.89：主要疾病史已询问，接受"既往体健""无重大疾病"等回答，满足诊疗需求
- 0.7-0.79：基本疾病史信息已获取，但部分重要疾病询问不够明确
- 0.6-0.69：疾病史基本询问已进行，但不够全面
- 0.5-0.59：缺少部分重要疾病史的询问
- 0.0-0.49：疾病史询问严重缺失，未进行基本询问

**重要原则**：
- "既往体健""无慢性疾病史""否认传染病史"等否定性回答视为有效完整信息
- 对记不清具体疾病名称或时间的回答给予理解
- 重点关注是否存在影响当前诊疗的重要既往疾病，而非病史的详细程度"""
        
        elif task_name == "预防接种史":
            return """**预防接种史评估标准**：
- 0.9-1.0：疫苗接种史已询问，包括"疫苗接种随当地""无特殊疫苗接种史"等否定性回答视为完整
- 0.8-0.89：疫苗接种史已询问，接受"按常规接种""无特殊要求"等回答，满足诊疗需求
- 0.7-0.79：疫苗接种史基本询问已进行，但部分重要疫苗询问不够明确
- 0.6-0.69：疫苗接种史询问已进行，但不够全面
- 0.5-0.59：缺少疫苗接种史的询问
- 0.0-0.49：疫苗接种史询问严重缺失，未进行基本询问

**重要原则**：
- "预防接种随当地""按常规接种""无特殊疫苗接种史"等回答视为有效完整信息
- 对记不清具体疫苗名称或接种时间的回答给予理解
- 重点关注是否存在影响当前诊疗的特殊疫苗接种情况"""
        
        elif task_name == "手术外伤史":
            return """**手术外伤史评估标准**：
- 0.9-1.0：手术外伤史已询问，包括"无手术史""无重大外伤史""否认手术外伤史"等否定性回答视为完整
- 0.8-0.89：手术外伤史已询问，接受"无相关手术""无重大外伤"等回答，满足诊疗需求
- 0.7-0.79：手术外伤史已询问，但回答不够明确
- 0.6-0.69：手术外伤史询问已进行，但不够全面
- 0.5-0.59：缺少手术外伤史的询问
- 0.0-0.49：手术外伤史询问严重缺失，未进行基本询问

**重要原则**：
- "无手术史""无外伤史""否认手术外伤史"等否定性回答视为有效完整信息
- 对记不清具体手术时间或细节的回答给予理解
- 重点关注是否存在影响当前诊疗的手术外伤史"""
        
        elif task_name == "输血史":
            return """**输血史评估标准**：
- 0.9-1.0：输血史已询问，包括"无输血史""否认输血史""无相关输血"等否定性回答视为完整
- 0.8-0.89：输血史已询问，接受"无输血需求""未接受过输血"等回答，满足诊疗需求
- 0.7-0.79：输血史已询问，但回答不够明确
- 0.6-0.69：输血史询问已进行，但不够全面
- 0.5-0.59：缺少输血史的询问
- 0.0-0.49：输血史询问严重缺失，未进行基本询问

**重要原则**：
- "无输血史""否认输血史""未接受过输血"等否定性回答视为有效完整信息
- 对记不清具体输血时间或细节的回答给予理解
- 重点关注是否存在影响当前诊疗的输血史"""
        
        elif task_name == "过敏史":
            return """**过敏史评估标准**：
- 0.9-1.0：过敏史已询问，包括"无过敏史""否认过敏史""无药物食物过敏"等否定性回答视为完整
- 0.8-0.89：过敏史已询问，接受"无过敏""未发现过敏"等回答，满足诊疗需求
- 0.7-0.79：过敏史基本询问已进行，但不够明确
- 0.6-0.69：过敏史询问已进行，但不够全面
- 0.5-0.59：缺少过敏史的询问
- 0.0-0.49：过敏史询问严重缺失，未进行基本询问

**重要原则**：
- "无过敏史""否认过敏史""无药物过敏"等否定性回答视为有效完整信息
- 对记不清具体过敏源或反应的回答给予理解
- 重点关注是否存在影响当前诊疗的过敏史"""
        
        else:
            # 默认评分标准
            return """**通用评分标准**（病史阶段专用，强调否定性回答价值）：
- 0.9-1.0：相关病史信息已询问，包括"无异常""未发生""记不清"等否定性回答视为完整有效
- 0.8-0.89：重要病史信息已询问，接受"无相关""正常""无特殊"等回答，满足诊疗需求
- 0.7-0.79：关键病史信息已询问，但部分询问不够明确
- 0.6-0.69：基本病史信息已获取，但询问不够全面
- 0.5-0.59：缺少重要病史信息的询问
- 0.0-0.49：病史询问严重缺失，未进行基本询问

**重要原则**：
- 所有否定性回答（"无""未发生""否认""正常"）均视为有效完整的临床信息
- 对时间久远或非关键细节的记忆模糊回答给予充分理解
- 重点关注是否存在影响诊疗的异常情况，而非信息描述的详细程度""",