#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Content Judger
内容审核器 - 重构版本，使用动态提示词和JSON处理，支持真实的审核格式
"""

import logging
from typing import Dict, Any, Tuple, Optional, List
import json

from ..config import AlgorithmConfig
from ..core import AIService, OutputManager, PromptManager, JSONProcessor
from ..exceptions import ContentGenerationError

logger = logging.getLogger(__name__)


class ContentJudger:
    """
    内容审核器 - 重构版本
    负责审核生成的内容质量，支持配置化参数和动态提示词
    """

    def __init__(self, config: AlgorithmConfig):
        """
        初始化内容审核器

        Args:
            config: 算法配置
        """
        self.config = config
        self.ai_service = AIService(config.ai_model)
        self.output_manager = OutputManager(config.output)
        self.prompt_manager = PromptManager(config.prompts, config.resources)
        
        # 初始化JSON处理器
        self.json_processor = JSONProcessor(
            enable_repair=config.content_generation.enable_json_repair,
            max_repair_attempts=config.content_generation.json_repair_attempts
        )
        
        # 获取任务特定的模型配置和字段配置
        self.task_model_config = config.ai_model.get_task_config("content_judging")
        self.field_config = config.content_generation.result_field_mapping.get("content_judging", {})
        
        # 审核阈值配置
        self.judge_threshold = config.content_generation.judge_threshold
        
        logger.info(f"内容审核器初始化完成，使用模型参数: {self.task_model_config}")

    async def judge_content(
        self,
        tweet_content: str,
        object_content: str,
        product_content: str,
        refer_content: str = "",
        content_metadata: Optional[Dict[str, Any]] = None,
        **kwargs
    ) -> Tuple[bool, str, float, Dict[str, Any]]:
        """
        审核内容质量

        Args:
            tweet_content: 待审核的文案内容
            object_content: 景区/对象信息
            product_content: 产品信息
            refer_content: 参考内容
            content_metadata: 内容元数据
            **kwargs: 其他参数

        Returns:
            Tuple[是否通过, 错误信息, 置信度, 审核结果详情]

        Raises:
            ContentGenerationError: 审核失败时抛出
        """
        try:
            logger.info("开始执行内容审核流程")

            # 1. 构建提示词
            system_prompt = self.prompt_manager.get_prompt("content_judging", "system")
            user_prompt_template = self.prompt_manager.get_prompt("content_judging", "user")
            
            # 格式化用户提示词（根据实际judgeContent/user.txt格式）
            user_prompt = self.prompt_manager.format_prompt(
                user_prompt_template,
                object_content=object_content,
                product_content=product_content,
                refer_content=refer_content,
                tweet_content=tweet_content,
                **kwargs
            )

            # 保存提示词（如果配置允许）
            if self.config.output.save_prompts:
                self.output_manager.save_text(system_prompt, "system_prompt", "content_judging")
                self.output_manager.save_text(user_prompt, "user_prompt", "content_judging")

            # 2. 调用AI审核
            content, input_tokens, output_tokens, elapsed_time = await self.ai_service.generate_text(
                system_prompt=system_prompt,
                user_prompt=user_prompt,
                stage="内容审核",
                **self.task_model_config
            )

            # 保存原始响应（如果配置允许）
            if self.config.output.save_raw_responses:
                self.output_manager.save_text(content, "raw_response", "content_judging")

            # 3. 解析审核结果
            is_passed, error_message, confidence, judge_result = self._parse_judge_result(content)

            # 4. 保存审核结果
            complete_result = {
                "original_content": tweet_content,
                "judge_result": judge_result,
                "is_passed": is_passed,
                "error_message": error_message,
                "confidence": confidence,
                "metadata": {
                    "content_metadata": content_metadata,
                    "judge_threshold": self.judge_threshold,
                    "model_config": self.task_model_config,
                    "field_config": self.field_config,
                    "tokens": {
                        "input": input_tokens,
                        "output": output_tokens
                    },
                    "elapsed_time": elapsed_time
                }
            }
            
            self.output_manager.save_json(complete_result, "judged_content")

            # 5. 保存元数据
            self.output_manager.save_metadata(complete_result["metadata"], "content_judging")

            logger.info(f"内容审核完成，结果: {'通过' if is_passed else '不通过'}, 置信度: {confidence:.2f}")
            return is_passed, error_message, confidence, judge_result

        except Exception as e:
            error_msg = f"内容审核失败: {str(e)}"
            logger.error(error_msg, exc_info=True)
            raise ContentGenerationError(error_msg)

    def _parse_judge_result(self, raw_output: str) -> Tuple[bool, str, float, Dict[str, Any]]:
        """
        解析审核结果

        Args:
            raw_output: AI原始输出

        Returns:
            Tuple[是否通过, 错误信息, 置信度, 完整结果]
        """
        try:
            # 使用JSON处理器解析
            parsed_data = self.json_processor.parse_llm_output(
                raw_output=raw_output,
                expected_fields=self.field_config.get("expected_fields", ["analysis", "title", "content"]),
                required_fields=self.field_config.get("required_fields", ["title", "content"])
            )

            # 根据实际judgeContent/system.txt的输出格式进行解析
            if isinstance(parsed_data, dict):
                judge_result = self._normalize_judge_data(parsed_data)
            else:
                # 回退处理
                judge_result = self._create_fallback_judge_data(raw_output)

            # 判断是否通过
            is_passed, error_message, confidence = self._evaluate_pass_status(judge_result)

            return is_passed, error_message, confidence, judge_result

        except Exception as e:
            logger.error(f"审核结果解析失败: {e}")
            # 返回保守的失败结果
            return False, f"解析失败: {str(e)}", 0.0, {"error": str(e), "raw_output": raw_output}

    def _normalize_judge_data(self, parsed_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        标准化审核数据格式

        Args:
            parsed_data: 解析后的数据

        Returns:
            标准化后的审核结果字典
        """
        # 根据实际judgeContent/system.txt的输出格式进行标准化
        normalized_data = {
            # 核心字段（根据实际system.txt的输出格式）
            "analysis": parsed_data.get("analysis", ""),
            "title": parsed_data.get("title", ""),
            "content": parsed_data.get("content", ""),
            
            # 计算字段
            "has_analysis": bool(parsed_data.get("analysis", "").strip()),
            "title_changed": parsed_data.get("title", "") != "",
            "content_changed": parsed_data.get("content", "") != "",
            "analysis_length": len(parsed_data.get("analysis", "")),
            
            # 元数据
            "metadata": {
                "original_parsed_data": parsed_data,
                "normalization_version": "v1",
                "generated_at": self.output_manager.run_id
            }
        }

        return normalized_data

    def _create_fallback_judge_data(self, raw_output: str) -> Dict[str, Any]:
        """
        创建回退的审核数据（当JSON解析失败时）

        Args:
            raw_output: 原始输出

        Returns:
            回退的审核结果字典
        """
        # 尝试从原始文本中提取信息
        return {
            "analysis": raw_output,
            "title": "",
            "content": "",
            "has_analysis": bool(raw_output.strip()),
            "title_changed": False,
            "content_changed": False,
            "analysis_length": len(raw_output),
            "metadata": {
                "parsing_method": "fallback_text_extraction",
                "generated_at": self.output_manager.run_id,
                "original_raw_output": raw_output
            }
        }

    def _evaluate_pass_status(self, judge_result: Dict[str, Any]) -> Tuple[bool, str, float]:
        """
        评估是否通过审核

        Args:
            judge_result: 审核结果

        Returns:
            Tuple[是否通过, 错误信息, 置信度]
        """
        try:
            analysis = judge_result.get("analysis", "")
            title = judge_result.get("title", "")
            content = judge_result.get("content", "")

            # 基础检查：是否有分析内容
            if not analysis:
                return False, "缺少审核分析", 0.1

            # 检查是否有修改后的内容
            has_corrections = bool(title) or bool(content)
            
            # 根据分析内容进行判断（简单的关键词判断）
            analysis_lower = analysis.lower()
            negative_keywords = [
                "不符", "错误", "虚构", "不合理", "不准确", "缺少", "遗漏", 
                "超过", "违反", "不当", "problem", "error", "incorrect", "missing"
            ]
            
            positive_keywords = [
                "符合", "正确", "准确", "合理", "完整", "适当", "良好",
                "correct", "accurate", "appropriate", "good", "proper"
            ]

            negative_score = sum(1 for keyword in negative_keywords if keyword in analysis_lower)
            positive_score = sum(1 for keyword in positive_keywords if keyword in analysis_lower)

            # 计算置信度
            if has_corrections:
                # 如果有修改，说明原内容有问题，但修改后应该是通过的
                confidence = max(0.7, min(0.95, 0.7 + positive_score * 0.1))
                is_passed = True
                error_message = ""
            elif negative_score > positive_score:
                # 负面评价较多
                confidence = max(0.3, min(0.9, 0.5 + negative_score * 0.1))
                is_passed = False
                error_message = "内容质量不符合要求"
            else:
                # 正面评价较多或无明显问题
                confidence = max(0.6, min(0.95, 0.8 + positive_score * 0.05))
                is_passed = True
                error_message = ""

            # 应用阈值
            if confidence < self.judge_threshold:
                is_passed = False
                error_message = error_message or "审核置信度不足"

            return is_passed, error_message, confidence

        except Exception as e:
            logger.error(f"审核状态评估失败: {e}")
            return False, f"评估失败: {str(e)}", 0.0

    async def judge_content_batch(
        self,
        content_list: List[Dict[str, Any]]
    ) -> Dict[str, Tuple[bool, str, float, Dict[str, Any]]]:
        """
        批量审核内容

        Args:
            content_list: 内容列表，每个元素包含审核所需的参数

        Returns:
            内容ID->审核结果的字典
        """
        results = {}
        
        for i, content_item in enumerate(content_list):
            try:
                content_id = content_item.get('id', f'content_{i+1}')
                logger.info(f"批量审核内容 {i+1}/{len(content_list)}: {content_id}")
                
                result = await self.judge_content(**content_item)
                results[content_id] = result
                
            except Exception as e:
                logger.error(f"批量审核第 {i+1} 项失败: {e}")
                content_id = content_item.get('id', f'content_{i+1}')
                results[content_id] = (False, f"审核失败: {str(e)}", 0.0, {"error": str(e)})
        
        return results

    async def test_judging(self) -> bool:
        """
        测试内容审核功能

        Returns:
            测试是否成功
        """
        try:
            test_content = """
            {
                "title": "上海外滩一日游",
                "content": "上海外滩是著名的旅游景点，历史悠久，值得一游。",
                "tag": "#上海 #外滩 #一日游"
            }
            """
            
            is_passed, error_message, confidence, judge_result = await self.judge_content(
                tweet_content=test_content,
                object_content="上海外滩景区信息",
                product_content="外滩一日游产品"
            )
            
            return confidence > 0.0
            
        except Exception as e:
            logger.error(f"内容审核测试失败: {e}")
            return False

    def get_judge_stats(self) -> Dict[str, Any]:
        """
        获取审核统计信息

        Returns:
            统计信息字典
        """
        return {
            "task_model_config": self.task_model_config,
            "field_config": self.field_config,
            "judge_threshold": self.judge_threshold,
            "output_directory": str(self.output_manager.run_output_dir),
            "ai_model_info": self.ai_service.get_model_info(),
            "prompt_templates": self.prompt_manager.get_available_templates().get("content_judging", {}),
            "json_processor_enabled": self.json_processor.enable_repair
        } 