import os
from pathlib import Path
from datetime import datetime
from typing import Dict, Any
from jinja2 import Environment, FileSystemLoader

class PDFService:
    """PDF报告生成服务"""
    
    def __init__(self):
        # 模板目录
        self.template_dir = Path(__file__).parent.parent / "templates"
        self.template_dir.mkdir(exist_ok=True)
        
        # 输出目录
        self.output_dir = Path(__file__).parent.parent / "generated_reports"
        self.output_dir.mkdir(exist_ok=True)
        
        # 初始化Jinja2环境
        self.jinja_env = Environment(loader=FileSystemLoader(str(self.template_dir)))
    
    def generate_report(
        self, 
        filename: str, 
        analysis: Dict[str, Any],
        llm_type: str = "Coze Workflow"
    ) -> str:
        """
        生成PDF报告
        
        Args:
            filename: 原始文件名
            analysis: 分析结果
            llm_type: 使用的LLM类型
            
        Returns:
            生成的PDF文件路径
        """
        try:
            # 准备模板数据
            template_data = self._prepare_template_data(filename, analysis, llm_type)
            
            # 渲染HTML
            html_content = self._render_html(template_data)
            
            # 生成PDF
            pdf_path = self._generate_pdf(html_content, filename)
            
            return pdf_path
            
        except Exception as e:
            raise Exception(f"PDF生成失败: {str(e)}")
    
    def _prepare_template_data(
        self, 
        filename: str, 
        analysis: Dict[str, Any],
        llm_type: str
    ) -> Dict[str, Any]:
        """准备模板数据"""
        # 处理 key_findings
        key_findings = analysis.get("key_findings", [])
        if key_findings:
            # 如果是对象数组，提取文本
            key_findings = [
                item.get("finding", item.get("text", str(item)))
                if isinstance(item, dict) else str(item)
                for item in key_findings
            ]
        
        # 处理 abnormal_items
        abnormal_items = analysis.get("abnormal_items", [])
        if abnormal_items:
            processed_items = []
            for item in abnormal_items:
                if isinstance(item, dict):
                    processed_items.append(item)
                else:
                    processed_items.append({"name": str(item)})
            abnormal_items = processed_items
        
        # 处理 risk_assessment
        risk_assessment = analysis.get("risk_assessment", "未提供")
        if isinstance(risk_assessment, dict):
            # 如果是对象，转换为文本
            parts = []
            if risk_assessment.get("high_risk"):
                parts.append(f"【高风险】{'; '.join(risk_assessment['high_risk'])}")
            if risk_assessment.get("medium_risk"):
                parts.append(f"【中风险】{'; '.join(risk_assessment['medium_risk'])}")
            if risk_assessment.get("low_risk"):
                parts.append(f"【低风险】{'; '.join(risk_assessment['low_risk'])}")
            risk_assessment = "\n".join(parts) if parts else "未检测到明确风险"
        
        # 处理 recommendations
        recommendations = analysis.get("recommendations", [])
        if recommendations:
            recommendations = [
                item.get("recommendation", item.get("text", str(item)))
                if isinstance(item, dict) else str(item)
                for item in recommendations
            ]
        
        return {
            "filename": filename,
            "analysis_date": datetime.now().strftime("%Y年%m月%d日"),
            "llm_type": llm_type,
            "summary": analysis.get("summary", "暂无摘要"),
            "key_findings": key_findings,
            "abnormal_items": abnormal_items,
            "risk_assessment": risk_assessment,
            "recommendations": recommendations,
            "generation_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }
    
    def _render_html(self, template_data: Dict[str, Any]) -> str:
        """渲染HTML模板"""
        template = self.jinja_env.get_template("report_template.html")
        return template.render(**template_data)
    
    def _generate_pdf(self, html_content: str, original_filename: str) -> str:
        """将HTML转换为PDF"""
        try:
            # 生成PDF文件名
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            base_name = Path(original_filename).stem
            pdf_filename = f"{base_name}_分析报告_{timestamp}.pdf"
            pdf_path = self.output_dir / pdf_filename
            
            # 尝试使用 WeasyPrint（推荐，质量更好）
            try:
                from weasyprint import HTML, CSS
                HTML(string=html_content).write_pdf(
                    str(pdf_path),
                    stylesheets=[CSS(string='@page { size: A4; margin: 1cm; }')]
                )
            except ImportError:
                # 降级到 xhtml2pdf（更简单，无需额外依赖）
                print("  WeasyPrint 未安装，使用 xhtml2pdf 生成PDF...")
                from xhtml2pdf import pisa
                with open(pdf_path, "wb") as pdf_file:
                    pisa_status = pisa.CreatePDF(html_content, dest=pdf_file)
                    if pisa_status.err:
                        raise Exception("xhtml2pdf 生成失败")
            
            return str(pdf_path)
            
        except Exception as e:
            raise Exception(f"PDF转换失败: {str(e)}")
    
    def get_pdf_file(self, pdf_path: str) -> bytes:
        """读取PDF文件内容"""
        if not os.path.exists(pdf_path):
            raise FileNotFoundError("PDF文件不存在")
        
        with open(pdf_path, "rb") as f:
            return f.read()
    
    def generate_comprehensive_report(
        self,
        patient_name: str,
        template_data: Dict[str, Any]
    ) -> str:
        """
        生成综合健康报告（多份报告整合）
        
        Args:
            patient_name: 患者姓名
            template_data: 包含所有报告数据和分析结果的字典
            
        Returns:
            生成的PDF文件路径
        """
        try:
            # 准备综合报告模板数据
            comprehensive_data = self._prepare_comprehensive_data(patient_name, template_data)
            
            # 渲染HTML（使用综合报告模板）
            html_content = self._render_comprehensive_html(comprehensive_data)
            
            # 生成PDF
            timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
            pdf_filename = f"{patient_name}_综合健康报告_{timestamp}.pdf"
            pdf_path = self.output_dir / pdf_filename
            
            try:
                from weasyprint import HTML, CSS
                HTML(string=html_content).write_pdf(
                    str(pdf_path),
                    stylesheets=[CSS(string='@page { size: A4; margin: 1cm; }')]
                )
            except ImportError:
                # 如果 WeasyPrint 不可用，使用 xhtml2pdf
                from xhtml2pdf import pisa
                with open(pdf_path, "wb") as pdf_file:
                    pisa_status = pisa.CreatePDF(html_content, dest=pdf_file)
                    if pisa_status.err:
                        raise Exception("xhtml2pdf 生成失败")
            
            return str(pdf_path)
            
        except Exception as e:
            raise Exception(f"综合报告生成失败: {str(e)}")
    
    def _prepare_comprehensive_data(
        self,
        patient_name: str,
        template_data: Dict[str, Any]
    ) -> Dict[str, Any]:
        """准备综合报告模板数据"""
        analysis = template_data.get("analysis", {})
        
        # 处理分析结果（与单报告相同的逻辑）
        key_findings = analysis.get("key_findings", [])
        if key_findings:
            key_findings = [
                item.get("finding", item.get("text", str(item)))
                if isinstance(item, dict) else str(item)
                for item in key_findings
            ]
        
        abnormal_items = analysis.get("abnormal_items", [])
        if abnormal_items:
            processed_items = []
            for item in abnormal_items:
                if isinstance(item, dict):
                    processed_items.append(item)
                else:
                    processed_items.append({"name": str(item)})
            abnormal_items = processed_items
        
        risk_assessment = analysis.get("risk_assessment", "未提供")
        if isinstance(risk_assessment, dict):
            parts = []
            if risk_assessment.get("high_risk"):
                parts.append(f"【高风险】{'; '.join(risk_assessment['high_risk'])}")
            if risk_assessment.get("medium_risk"):
                parts.append(f"【中风险】{'; '.join(risk_assessment['medium_risk'])}")
            if risk_assessment.get("low_risk"):
                parts.append(f"【低风险】{'; '.join(risk_assessment['low_risk'])}")
            risk_assessment = "\n".join(parts) if parts else "未检测到明确风险"
        
        recommendations = analysis.get("recommendations", [])
        if recommendations:
            recommendations = [
                item.get("recommendation", item.get("text", str(item)))
                if isinstance(item, dict) else str(item)
                for item in recommendations
            ]
        
        return {
            "patient_name": patient_name,
            "report_count": template_data.get("report_count", 0),
            "report_list": template_data.get("report_list", []),
            "generation_date": template_data.get("generation_date", datetime.now().strftime("%Y年%m月%d日")),
            "summary": analysis.get("summary", "暂无摘要"),
            "key_findings": key_findings,
            "abnormal_items": abnormal_items,
            "risk_assessment": risk_assessment,
            "recommendations": recommendations,
            "generation_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }
    
    def _render_comprehensive_html(self, template_data: Dict[str, Any]) -> str:
        """渲染综合报告HTML模板"""
        template = self.jinja_env.get_template("comprehensive_report_template.html")
        return template.render(**template_data)
