"""
DeepSeek 健康评估与建议生成服务
用于生成"整体健康状况"和"功能性健康建议"内容

优化：优先使用模板中已有的项目解释，只有模板中没有的项目才调用 DeepSeek 生成
"""

import os
import json
import requests
from pathlib import Path
from typing import List, Dict, Any


class DeepSeekHealthService:
    """DeepSeek 健康内容生成服务"""
    
    def __init__(self, api_key: str = None):
        self.api_key = api_key or os.getenv("DEEPSEEK_API_KEY", "")
        self.api_url = "https://api.deepseek.com/v1/chat/completions"
        
        # 加载模板中的解释
        self.template_explanations = self._load_template_explanations()
    
    def _load_template_explanations(self) -> Dict[str, Dict[str, str]]:
        """加载模板中已有的项目解释"""
        explanations_file = Path(__file__).parent.parent / "template_explanations.json"
        
        if explanations_file.exists():
            try:
                with open(explanations_file, 'r', encoding='utf-8') as f:
                    explanations = json.load(f)
                print(f"  ✓ 已加载 {len(explanations)} 个模板解释")
                return explanations
            except Exception as e:
                print(f"  ⚠️ 加载模板解释失败: {e}")
        
        return {}
    
    def get_template_explanation(self, abb: str) -> Dict[str, str]:
        """
        获取模板中的项目解释
        
        Args:
            abb: 项目缩写
            
        Returns:
            {"clinical_en": "...", "clinical_cn": "..."} 或空字典
        """
        # 尝试多种匹配方式
        abb_upper = abb.upper().strip()
        
        # 直接匹配
        if abb_upper in self.template_explanations:
            return self.template_explanations[abb_upper]
        
        # 去除特殊字符后匹配
        abb_clean = ''.join(c for c in abb_upper if c.isalnum())
        for key, value in self.template_explanations.items():
            key_clean = ''.join(c for c in key if c.isalnum())
            if abb_clean == key_clean:
                return value
        
        return {}
    
    def is_available(self) -> bool:
        """检查服务是否可用"""
        return bool(self.api_key)
    
    def call_deepseek(self, prompt: str) -> str:
        """调用 DeepSeek API"""
        if not self.api_key:
            raise ValueError("未配置 DEEPSEEK_API_KEY")
        
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }
        
        data = {
            "model": "deepseek-chat",
            "messages": [{"role": "user", "content": prompt}],
            "temperature": 0.1,
            "max_tokens": 8000
        }
        
        response = requests.post(
            self.api_url, 
            headers=headers, 
            json=data, 
            timeout=120
        )
        response.raise_for_status()
        return response.json()["choices"][0]["message"]["content"]
    
    def collect_abnormal_items(self, analysis: Dict[str, Any]) -> List[Dict[str, str]]:
        """
        从分析结果中收集异常项
        
        Args:
            analysis: LLM 分析结果，包含 abnormal_items 字段
            
        Returns:
            异常项列表
        """
        abnormal_items = []
        
        # 从 abnormal_items 字段提取
        raw_items = analysis.get("abnormal_items", [])
        
        for item in raw_items:
            if isinstance(item, dict):
                abnormal_items.append({
                    "name": item.get("name", ""),
                    "abb": item.get("abb", item.get("name", "")),
                    "result": str(item.get("result", item.get("value", ""))),
                    "reference": item.get("reference", ""),
                    "unit": item.get("unit", ""),
                    "level": item.get("level", ""),
                    "point": "↑" if item.get("level") == "high" else ("↓" if item.get("level") == "low" else "")
                })
            elif isinstance(item, str):
                # 如果是字符串格式，尝试解析
                abnormal_items.append({
                    "name": item,
                    "abb": "",
                    "result": "",
                    "reference": "",
                    "unit": "",
                    "level": "",
                    "point": ""
                })
        
        return abnormal_items
    
    def get_item_explanations(self, abnormal_items: List[Dict[str, str]]) -> Dict[str, Dict[str, str]]:
        """
        为异常项获取解释（优先使用模板中的解释，缺失的才调用 DeepSeek 生成）
        
        Args:
            abnormal_items: 异常项列表
            
        Returns:
            {
                "ABB": {"clinical_en": "...", "clinical_cn": "..."},
                ...
            }
        """
        explanations = {}
        items_need_generation = []
        
        print("\n  📋 检查模板中的项目解释...")
        
        for item in abnormal_items:
            abb = item.get("abb", "").upper().strip()
            name = item.get("name", "")
            
            if not abb:
                continue
            
            # 尝试从模板获取解释
            template_exp = self.get_template_explanation(abb)
            
            if template_exp and template_exp.get("clinical_en") and template_exp.get("clinical_cn"):
                explanations[abb] = template_exp
                print(f"    ✓ {abb}: 使用模板解释")
            else:
                items_need_generation.append(item)
                print(f"    ○ {abb}: 需要生成解释")
        
        # 如果有需要生成的项目，调用 DeepSeek
        if items_need_generation and self.api_key:
            print(f"\n  🤖 调用 DeepSeek 为 {len(items_need_generation)} 个项目生成解释...")
            generated = self._generate_missing_explanations(items_need_generation)
            explanations.update(generated)
        
        return explanations
    
    def _generate_missing_explanations(self, items: List[Dict[str, str]]) -> Dict[str, Dict[str, str]]:
        """
        调用 DeepSeek 为缺失解释的项目生成临床意义
        
        Args:
            items: 需要生成解释的项目列表
            
        Returns:
            生成的解释字典
        """
        if not items:
            return {}
        
        # 构建项目描述
        items_desc = []
        for item in items:
            desc = f"- {item['abb']}: {item['name']}"
            if item.get('result'):
                desc += f", 结果: {item['result']}"
            if item.get('unit'):
                desc += f" {item['unit']}"
            if item.get('reference'):
                desc += f", 参考范围: {item['reference']}"
            items_desc.append(desc)
        
        prompt = f"""你是一位医学检验专家，请为以下医疗检测项目生成临床意义解释。

## 需要解释的项目：
{chr(10).join(items_desc)}

## 要求：
1. 为每个项目提供英文和中文的临床意义解释
2. 解释应包含：该指标的作用、正常范围的意义、异常时可能的原因
3. 语言专业但易于理解
4. 每个解释约50-100字

## 输出格式（JSON）：
```json
{{
    "ABB1": {{
        "clinical_en": "English clinical significance...",
        "clinical_cn": "中文临床意义..."
    }},
    "ABB2": {{
        "clinical_en": "...",
        "clinical_cn": "..."
    }}
}}
```

只返回JSON，不要其他说明。"""
        
        try:
            response = self.call_deepseek(prompt)
            
            # 解析 JSON
            if "```json" in response:
                response = response.split("```json")[1].split("```")[0]
            elif "```" in response:
                response = response.split("```")[1].split("```")[0]
            
            result = json.loads(response.strip())
            print(f"    ✓ 成功生成 {len(result)} 个项目的解释")
            return result
        except Exception as e:
            print(f"    ✗ 生成解释失败: {e}")
            return {}
    
    def generate_health_assessment(self, abnormal_items: List[Dict[str, str]]) -> Dict[str, Any]:
        """
        生成"整体健康状况"评估内容
        
        Args:
            abnormal_items: 异常项列表
            
        Returns:
            包含多个小节的健康评估内容
        """
        if not self.api_key or not abnormal_items:
            return {"sections": []}
        
        # 构建异常项描述
        abnormal_desc = []
        for item in abnormal_items:
            direction = "偏高" if item.get("point") in ["↑", "H", "高"] or item.get("level") == "high" else "偏低"
            desc = f"- {item['name']}"
            if item.get('abb'):
                desc += f" ({item['abb']})"
            desc += f": {item['result']}"
            if item.get('unit'):
                desc += f" {item['unit']}"
            desc += f" ({direction}"
            if item.get('reference'):
                desc += f", 参考范围: {item['reference']}"
            desc += ")"
            abnormal_desc.append(desc)
        
        prompt = f"""你是一位功能医学专家，请根据以下所有异常检测指标，撰写"整体健康状况评估"的内容。

## 异常指标：
{chr(10).join(abnormal_desc)}

## 要求：
1. 根据异常指标的类型，自动分成合适的小节（如血液学、内分泌、免疫、代谢等，根据实际异常项决定）
2. 每个小节包含英文和中文两个版本
3. 从功能医学和整体健康角度分析
4. 解释可能的原因和健康影响
5. 语言专业但易于理解
6. 每个小节的每个语言版本约150-250字

## 输出格式（JSON）：
```json
{{
    "sections": [
        {{
            "title_en": "(I) Section Title in English",
            "title_cn": "（一）中文小节标题",
            "content_en": "English analysis content...",
            "content_cn": "中文分析内容..."
        }}
    ]
}}
```

只返回JSON，不要其他说明。根据实际异常项情况决定分几个小节，不要硬套固定模板。"""
        
        try:
            response = self.call_deepseek(prompt)
            
            # 解析 JSON
            if "```json" in response:
                response = response.split("```json")[1].split("```")[0]
            elif "```" in response:
                response = response.split("```")[1].split("```")[0]
            
            result = json.loads(response.strip())
            print(f"    ✓ 生成健康评估内容，共 {len(result.get('sections', []))} 个小节")
            return result
        except Exception as e:
            print(f"    ✗ 生成健康评估内容失败: {e}")
            return {"sections": []}
    
    def generate_health_advice(self, abnormal_items: List[Dict[str, str]]) -> Dict[str, Any]:
        """
        生成"功能性健康建议"内容
        
        Args:
            abnormal_items: 异常项列表
            
        Returns:
            包含5个固定小节的健康建议内容
        """
        if not self.api_key or not abnormal_items:
            return {"sections": []}
        
        # 异常项描述
        abnormal_desc = []
        for item in abnormal_items:
            direction = "偏高" if item.get("point") in ["↑", "H", "高"] or item.get("level") == "high" else "偏低"
            desc = f"- {item['name']}"
            if item.get('abb'):
                desc += f" ({item['abb']})"
            desc += f": {item['result']}"
            if item.get('unit'):
                desc += f" {item['unit']}"
            desc += f" ({direction})"
            abnormal_desc.append(desc)
        
        prompt = f"""你是一位功能医学专家，请根据以下异常检测指标，撰写"功能医学健康建议"的内容。

## 异常指标：
{chr(10).join(abnormal_desc)}

## 要求：
1. 必须包含以下5个固定小节（按顺序）：
   - Nutrition Intervention 营养干预
   - Exercise Intervention 运动干预  
   - Sleep & Stress Management 睡眠与压力管理
   - Lifestyle Adjustment 生活方式调整
   - Long-term Follow-up Plan 长期随访计划
2. 每个小节针对这些异常指标提供具体、可执行的建议
3. 从功能医学角度出发，强调预防和整体调理
4. 每个小节包含3-5条具体建议措施
5. 语言专业但易于理解
6. 分别提供英文和中文版本
7. 每个小节的每个语言版本约200-300字

## 输出格式（JSON）：
```json
{{
    "sections": [
        {{
            "title_en": "Nutrition Intervention",
            "title_cn": "营养干预",
            "content_en": "English nutrition advice...",
            "content_cn": "中文营养建议..."
        }},
        {{
            "title_en": "Exercise Intervention",
            "title_cn": "运动干预",
            "content_en": "...",
            "content_cn": "..."
        }},
        {{
            "title_en": "Sleep & Stress Management",
            "title_cn": "睡眠与压力管理",
            "content_en": "...",
            "content_cn": "..."
        }},
        {{
            "title_en": "Lifestyle Adjustment",
            "title_cn": "生活方式调整",
            "content_en": "...",
            "content_cn": "..."
        }},
        {{
            "title_en": "Long-term Follow-up Plan",
            "title_cn": "长期随访计划",
            "content_en": "...",
            "content_cn": "..."
        }}
    ]
}}
```

只返回JSON，不要其他说明。"""
        
        try:
            response = self.call_deepseek(prompt)
            
            # 解析 JSON
            if "```json" in response:
                response = response.split("```json")[1].split("```")[0]
            elif "```" in response:
                response = response.split("```")[1].split("```")[0]
            
            result = json.loads(response.strip())
            print(f"    ✓ 生成健康建议内容，共 {len(result.get('sections', []))} 个小节")
            return result
        except Exception as e:
            print(f"    ✗ 生成健康建议内容失败: {e}")
            return {"sections": []}
    
    def generate_health_content(self, analysis: Dict[str, Any]) -> Dict[str, Any]:
        """
        生成完整的健康评估和建议内容
        
        优化：优先使用模板中已有的项目解释，只有模板中没有的项目才调用 DeepSeek 生成
        
        Args:
            analysis: LLM 分析结果
            
        Returns:
            包含 health_assessment, health_advice, item_explanations 的字典
        """
        if not self.is_available():
            print("  ⚠️ DeepSeek API Key 未配置，跳过健康内容生成")
            return {}
        
        print("\n============================================================")
        print("DeepSeek 健康内容生成")
        print("============================================================")
        
        # 收集异常项
        print("\n  📝 正在收集异常项...")
        abnormal_items = self.collect_abnormal_items(analysis)
        
        if not abnormal_items:
            print("    ℹ️ 没有检测到异常项目，跳过内容生成")
            return {}
        
        print(f"    发现 {len(abnormal_items)} 个异常项目:")
        for item in abnormal_items[:10]:
            direction = "↑" if item.get("level") == "high" or item.get("point") == "↑" else "↓"
            print(f"      - {item['name']}: {item['result']} {direction}")
        if len(abnormal_items) > 10:
            print(f"      ... 等共 {len(abnormal_items)} 项")
        
        # 获取项目解释（优先使用模板，缺失的才生成）
        item_explanations = self.get_item_explanations(abnormal_items)
        
        # 统计使用情况
        template_count = sum(1 for abb in item_explanations if self.get_template_explanation(abb))
        generated_count = len(item_explanations) - template_count
        print(f"\n  📊 解释来源统计: 模板 {template_count} 个, DeepSeek生成 {generated_count} 个")
        
        # 生成健康评估
        print("\n  🤖 正在调用 DeepSeek 生成整体健康状况...")
        health_assessment = self.generate_health_assessment(abnormal_items)
        
        # 生成健康建议
        print("\n  🤖 正在调用 DeepSeek 生成功能性健康建议...")
        health_advice = self.generate_health_advice(abnormal_items)
        
        print("\n  ✓ 健康内容生成完成")
        
        return {
            "health_assessment": health_assessment,
            "health_advice": health_advice,
            "abnormal_items": abnormal_items,
            "item_explanations": item_explanations  # 包含每个项目的解释
        }
