"""
报告生成器
负责生成审查报告和多维评分
"""

import asyncio
from typing import Dict, List, Any, Optional, Callable
from dataclasses import dataclass
from datetime import datetime
import json

from foundation.logger.loggering import server_logger as logger

@dataclass
class DimensionScores:
    """四维评分"""
    safety: int      # 安全维度评分
    quality: int     # 质量维度评分
    schedule: int    # 进度维度评分
    cost: int        # 成本维度评分

@dataclass
class FinalReport:
    """最终报告"""
    file_id: str
    document_name: str
    risk_stats: Dict[str, int]
    dimension_scores: DimensionScores
    summary_report: str
    multidimensional_report: str
    recommendations: List[str]
    generated_at: datetime

class ReportGenerator:
    """报告生成器"""

    def __init__(self):
        self.risk_weight_mapping = {
            "high": 3,
            "medium": 2,
            "low": 1
        }

    async def generate_report(self, file_id: str, review_results: Dict[str, Any],
                            progress_callback: Optional[Callable[[int, str], None]] = None) -> FinalReport:
        """
        生成审查报告

        Args:
            file_id: 文件ID
            review_results: AI审查结果
            progress_callback: 进度回调函数

        Returns:
            FinalReport: 最终报告
        """
        try:
            logger.info(f"开始生成报告，文件ID: {file_id}")

            if progress_callback:
                progress_callback(20, "汇总审查结果")

            # 1. 数据汇总
            aggregated_data = await self._aggregate_results(review_results)

            if progress_callback:
                progress_callback(40, "计算多维评分")

            # 2. 计算四维评分
            dimension_scores = await self._calculate_dimension_scores(aggregated_data)

            if progress_callback:
                progress_callback(60, "生成总结报告")

            # 3. 生成总结报告
            summary_report = await self._generate_summary(aggregated_data, dimension_scores)

            if progress_callback:
                progress_callback(80, "生成多维报告")

            # 4. 生成多维报告
            multidimensional_report = await self._generate_multidimensional_report(
                aggregated_data, dimension_scores
            )

            if progress_callback:
                progress_callback(100, "报告生成完成")

            # 5. 生成建议
            recommendations = await self._generate_recommendations(aggregated_data, dimension_scores)

            final_report = FinalReport(
                file_id=file_id,
                document_name=f"施工方案审查报告_{file_id}",
                risk_stats=aggregated_data.get('risk_distribution', {}),
                dimension_scores=dimension_scores,
                summary_report=summary_report,
                multidimensional_report=multidimensional_report,
                recommendations=recommendations,
                generated_at=datetime.now()
            )

            logger.info(f"报告生成完成，文件ID: {file_id}")
            return final_report

        except Exception as e:
            logger.error(f"报告生成失败: {str(e)}")
            raise

    async def _aggregate_results(self, review_results: Dict[str, Any]) -> Dict[str, Any]:
        """汇总审查结果"""
        summary = review_results.get('summary', {})
        risk_stats = summary.get('risk_distribution', {})

        # 按风险等级分类问题
        issues_by_risk = {
            "high": [],
            "medium": [],
            "low": []
        }

        # 分析每个审查单元的问题
        for result in review_results.get('review_results', []):
            risk_level = result.overall_risk
            issues_by_risk[risk_level].append({
                'unit_index': result.unit_index,
                'chapter': result.unit_content.get('chapter', ''),
                'title': result.unit_content.get('title', ''),
                'content': result.unit_content.get('original_content', ''),
                'basic_issues': self._extract_issues(result.basic_compliance),
                'technical_issues': self._extract_issues(result.technical_compliance),
                'rag_suggestions': result.rag_enhanced.get('enhanced_suggestions', [])
            })

        return {
            'risk_distribution': risk_stats,
            'issues_by_risk': issues_by_risk,
            'total_units': review_results.get('total_units', 0),
            'successful_units': review_results.get('successful_units', 0),
            'failed_units': review_results.get('failed_units', 0)
        }

    async def _calculate_dimension_scores(self, aggregated_data: Dict[str, Any]) -> DimensionScores:
        """计算四维评分"""
        risk_stats = aggregated_data.get('risk_distribution', {})
        total_issues = risk_stats.get('high', 0) + risk_stats.get('medium', 0) + risk_stats.get('low', 0)
        total_units = aggregated_data.get('total_units', 1)

        # 基础评分计算
        base_score = max(0, 100 - (risk_stats.get('high', 0) * 10) - (risk_stats.get('medium', 0) * 5) - (risk_stats.get('low', 0) * 2))

        # 安全维度评分 (安全风险权重更高)
        safety_score = max(0, base_score - (risk_stats.get('high', 0) * 15) - (risk_stats.get('medium', 0) * 8))

        # 质量维度评分
        quality_score = max(0, base_score - (risk_stats.get('high', 0) * 12) - (risk_stats.get('medium', 0) * 6))

        # 进度维度评分
        schedule_score = max(0, base_score - (risk_stats.get('medium', 0) * 8) - (risk_stats.get('low', 0) * 3))

        # 成本维度评分
        cost_score = max(0, base_score - (risk_stats.get('high', 0) * 10) - (risk_stats.get('medium', 0) * 5))

        return DimensionScores(
            safety=min(100, safety_score),
            quality=min(100, quality_score),
            schedule=min(100, schedule_score),
            cost=min(100, cost_score)
        )

    async def _generate_summary(self, aggregated_data: Dict[str, Any], dimension_scores: DimensionScores) -> str:
        """生成总结报告"""
        risk_stats = aggregated_data.get('risk_distribution', {})
        high_risk = risk_stats.get('high', 0)
        medium_risk = risk_stats.get('medium', 0)
        low_risk = risk_stats.get('low', 0)
        total_issues = high_risk + medium_risk + low_risk

        # 生成总结报告
        summary_parts = []

        # 整体评价
        if high_risk == 0 and medium_risk <= 2:
            summary_parts.append("该施工方案整体符合规范要求，质量良好。")
        elif high_risk <= 2:
            summary_parts.append("该施工方案基本符合规范要求，存在少量问题需要整改。")
        else:
            summary_parts.append("该施工方案存在较多高风险问题，需要重点整改。")

        # 风险统计
        summary_parts.append(f"发现风险问题 {total_issues} 个，其中高风险 {high_risk} 个，中风险 {medium_risk} 个，低风险 {low_risk} 个。")

        # 评分说明
        avg_score = (dimension_scores.safety + dimension_scores.quality +
                     dimension_scores.schedule + dimension_scores.cost) / 4

        if avg_score >= 85:
            summary_parts.append(f"综合评分 {avg_score:.1f} 分，表现优秀。")
        elif avg_score >= 70:
            summary_parts.append(f"综合评分 {avg_score:.1f} 分，表现良好。")
        else:
            summary_parts.append(f"综合评分 {avg_score:.1f} 分，需要改进。")

        return " ".join(summary_parts)

    async def _generate_multidimensional_report(self, aggregated_data: Dict[str, Any],
                                              dimension_scores: DimensionScores) -> str:
        """生成多维报告"""
        report_parts = []

        # 安全维度分析
        safety_desc = self._get_score_description(dimension_scores.safety, "安全")
        report_parts.append(f"安全维度评分 {dimension_scores.safety} 分：{safety_desc}")

        # 质量维度分析
        quality_desc = self._get_score_description(dimension_scores.quality, "质量")
        report_parts.append(f"质量维度评分 {dimension_scores.quality} 分：{quality_desc}")

        # 进度维度分析
        schedule_desc = self._get_score_description(dimension_scores.schedule, "进度")
        report_parts.append(f"进度维度评分 {dimension_scores.schedule} 分：{schedule_desc}")

        # 成本维度分析
        cost_desc = self._get_score_description(dimension_scores.cost, "成本")
        report_parts.append(f"成本维度评分 {dimension_scores.cost} 分：{cost_desc}")

        # 综合建议
        report_parts.append("\n综合建议：")
        if dimension_scores.safety < 70:
            report_parts.append("• 重点关注安全管理，完善安全技术措施。")
        if dimension_scores.quality < 70:
            report_parts.append("• 加强质量控制，完善施工工艺标准。")
        if dimension_scores.schedule < 70:
            report_parts.append("• 优化进度管理，确保工期可控。")
        if dimension_scores.cost < 70:
            report_parts.append("• 加强成本控制，避免预算超支。")

        return "\n".join(report_parts)

    async def _generate_recommendations(self, aggregated_data: Dict[str, Any],
                                       dimension_scores: DimensionScores) -> List[str]:
        """生成改进建议"""
        recommendations = []

        # 基于风险分布的建议
        risk_stats = aggregated_data.get('risk_distribution', {})
        high_risk_issues = aggregated_data.get('issues_by_risk', {}).get('high', [])

        if high_risk_issues:
            recommendations.append("立即处理高风险问题：")
            for issue in high_risk_issues[:3]:  # 取前3个高风险问题
                recommendations.append(f"• {issue.get('title', '未知章节')}：{issue.get('content', '')[:50]}...")

        # 基于评分的建议
        if dimension_scores.safety < 80:
            recommendations.append("完善安全管理体系：")
            recommendations.append("• 补充安全技术交底记录")
            recommendations.append("• 加强现场安全防护措施")

        if dimension_scores.quality < 80:
            recommendations.append("提升施工质量：")
            recommendations.append("• 完善施工工艺标准")
            recommendations.append("• 加强质量检查频次")

        if dimension_scores.schedule < 80:
            recommendations.append("优化进度管理：")
            recommendations.append("• 细化施工进度计划")
            recommendations.append("• 建立进度预警机制")

        return recommendations

    def _extract_issues(self, compliance_result: Dict[str, Any]) -> List[str]:
        """提取问题描述"""
        if isinstance(compliance_result, dict) and 'error' in compliance_result:
            return [f"检查失败: {compliance_result['error']}"]

        # 根据实际审查结果结构提取问题
        # 这里需要根据实际的审查结果结构来实现
        return []

    def _get_score_description(self, score: int, dimension: str) -> str:
        """获取评分描述"""
        if score >= 90:
            return f"{dimension}管理优秀，符合规范要求，无明显风险。"
        elif score >= 80:
            return f"{dimension}管理良好，基本符合规范，存在少量细节问题。"
        elif score >= 70:
            return f"{dimension}管理一般，需要改进部分环节。"
        elif score >= 60:
            return f"{dimension}管理较差，存在较多问题需要整改。"
        else:
            return f"{dimension}管理差，存在严重问题，需要全面整改。"