"""
审查器基类
定义模型调用、提示词设定的基础接口
"""


import asyncio
import uuid
import time
from abc import ABC
from typing import Dict, Any, Optional
from dataclasses import dataclass
#from langfuse import obverse
from foundation.observability.monitoring.ai_trace_monitor import lf
from foundation.ai.agent.generate.model_generate import generate_model_client
from core.construction_review.component.reviewers.utils.prompt_loader import prompt_loader
from foundation.observability.logger.loggering import review_logger as logger


@dataclass
class ReviewResult:
    """审查结果基类"""
    success: bool
    details: Dict[str, Any]
    error_message: Optional[str] = None
    execution_time: Optional[float] = None


class BaseReviewer(ABC):
    """审查器基类"""

    def __init__(self):
        self.model_client = generate_model_client
        self.prompt_loader = prompt_loader
        self.reference_source = ""
    
    #@obverse
    async def  review(self, name: str, trace_id: str, reviewer_type: str, prompt_name: str, review_content: str, review_references: str = None,
                    reference_source: str = None, state:str =None,stage_name:str = None, timeout: int = 60, model_name: str = None,
                    function_name: str = None) -> ReviewResult:
        """
        执行审查

        Args:
            name: 审查器名称 (必填)
            trace_id: 追踪ID (必填)
            reviewer_type: 审查器类型 (basic, technical, rag, ai) (必填)
            prompt_name: 提示词名称 (必填)
                - basic: semantic_logic_check, completeness_check, timeliness_check, reference_check, sensitive_word_check
                - technical: mandatory_standards_check, technical_parameters_check, design_values_check
                - rag: rag_enhanced_review, vector_search_review, hybrid_search_review
                - ai: professional_suggestion, standardization_suggestion, completeness_suggestion, readability_suggestion
            review_content: 待审查内容 (必填)
            review_references: 审查参考内容 (可选)
            reference_source: 参考来源 (可选)
            state: 状态字典 (可选，用于进度更新)
            stage_name: 阶段名称 (可选，用于进度更新)
            timeout: 模型调用超时时间，默认60秒 (可选)
            model_name: 模型名称 (可选)，支持动态切换模型
                      支持的模型：doubao, qwen, deepseek, gemini,
                                  lq_qwen3_8b, lq_qwen3_8b_lq_lora,
                                  lq_qwen3_4b, qwen_local_14b
                      如果为None,则使用配置文件中的默认模型
            function_name: 功能名称 (可选)，如提供则从 model_setting.yaml 加载模型配置
                      支持的功能：doc_classification_secondary, doc_classification_tertiary,
                                  completeness_review_generate, completeness_review_classify,
                                  rag_query_understand, rag_answer_generate,
                                  sensitive_check, grammar_check

        Returns:
            ReviewResult: 审查结果
        """
        start_time = time.time()
        try:
            # 记录使用的模型
            if function_name:
                logger.info(f"开始执行 {name} 审查，trace_id: {trace_id}, 功能: {function_name}, 内容长度: {len(review_content)}")
            elif model_name:
                logger.info(f"开始执行 {name} 审查，trace_id: {trace_id}, 模型: {model_name}, 内容长度: {len(review_content)}")
            else:
                logger.info(f"开始执行 {name} 审查，trace_id: {trace_id}, 使用默认模型, 内容长度: {len(review_content)}")

            prompt_kwargs = {}
            prompt_kwargs["review_content"] = review_content
            prompt_kwargs["review_references"] = review_references or ""
            # 添加reference_source到提示词参数中
            # if reference_source:
            #     prompt_kwargs["reference_source"] = reference_source
            task_prompt_info = {
                "task_prompt": self.prompt_loader.get_prompt_template(reviewer_type, prompt_name, **prompt_kwargs),
                "task_name": name
            }

            # 调用模型,优先使用 function_name，其次使用 model_name
            invoke_kwargs = {
                "trace_id": trace_id,
                "task_prompt_info": task_prompt_info,
                "timeout": timeout,
            }
            if function_name:
                invoke_kwargs["function_name"] = function_name
            elif model_name:
                invoke_kwargs["model_name"] = model_name
            model_response = await self.model_client.get_model_generate_invoke(**invoke_kwargs)
            if reference_source:
                result = self.format_result(model_response, name, reference_source, review_references)
            else:
                result = self.format_result(model_response, name)

            result.execution_time = time.time() - start_time

            # 将审查结果转换为字典格式，添加到issues中
            review_result_data = {
                'name': name,
                'success': result.success,
                'details': result.details,
                'error_message': result.error_message,
                'execution_time': result.execution_time,
                'timestamp': time.time()
            }

            # 推送审查完成信息
            if state and state.get("progress_manager"):
                # 使用专门的事件类型，避免覆盖主进度的processing_flag
                asyncio.create_task(
                    state["progress_manager"].update_stage_progress(
                        callback_task_id=state["callback_task_id"],
                        stage_name=stage_name,
                        current=None,  # 明确不更新current，保持主流程进度
                        status="processing",
                        message=f"{name} 审查完成， 耗时: {result.execution_time:.2f}s",
                        issues=[review_result_data],
                        event_type="processing"  # 使用专门的事件类型
                    )
                )
            logger.info(f"{name} 审查完成， 耗时: {result.execution_time:.2f}s")

            return result

        except Exception as e:
            execution_time = time.time() - start_time
            error_msg = f"{name} 审查失败: {str(e)}"
            logger.error(error_msg, exc_info=True)

            return ReviewResult(
                success=False,
                details={},
                error_message=error_msg,
                execution_time=execution_time
            )
    def format_result(self, model_response: str, name: str = None,reference_source:str = None,review_references:str = None) -> ReviewResult:
        """
        格式化模型返回结果为ReviewResult对象
        """
        if reference_source:
            details = {"response": model_response}
            details["rag_reference_source"] = reference_source
            details["rag_review_references"] = review_references
        else:
            details = {"response": model_response}
        if name:
            details["name"] = name

        return ReviewResult(
            success=True,
            details=details,
            error_message=None
        )


