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


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.agent.monitor.ai_trace_monitor import lf
from foundation.agent.generate.model_generate import generate_model_client
from core.construction_review.component.reviewers.utils.prompt_loader import prompt_loader
from foundation.logger.loggering import server_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, review_location_label: str = ""):
        self.model_client = generate_model_client
        self.prompt_loader = prompt_loader
        self.review_location_label = review_location_label
    
    #@obverse
    async def review(self, name: str, trace_id: str, reviewer_type: str, prompt_name: str, review_content: str, review_references: str = None,
                    stage_name: str = None, state: dict = None, current_progress: int = 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: 审查参考内容 (可选)
            stage_name: 阶段名称 (可选，用于进度更新)
            state: 状态字典 (可选，用于进度更新)
            current_progress: 当前进度 (可选，用于进度更新)

        Returns:
            ReviewResult: 审查结果
        """
        start_time = time.time()
        try:
            # 添加进度更新
            # 安全检查：确保所有必要参数都存在才执行进度更新
            # if state and state.get("progress_manager") and stage_name and current_progress is not None:
            #     asyncio.create_task(
            #         state["progress_manager"].update_stage_progress(
            #             callback_task_id=state["callback_task_id"],
            #             stage_name=stage_name,
            #             current=current_progress,
            #             status="processing",
            #             message=f"开始进行：{name}"
            #         )
            #     )
            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 ""
            # 添加审查位置标签到提示词参数中
            if hasattr(self, 'review_location_label') and self.review_location_label:
                prompt_kwargs["review_location_label"] = self.review_location_label
            task_prompt_info = {
                "task_prompt": self.prompt_loader.get_prompt_template(reviewer_type, prompt_name, **prompt_kwargs),
                "task_name": name
            }

            # 调用模型
            model_response = await self.model_client.get_model_generate_invoke(
                trace_id=trace_id,
                task_prompt_info=task_prompt_info
            )

            # 格式化结果
            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) -> ReviewResult:
        """
        格式化模型返回结果为ReviewResult对象
        """
        details = {"response": model_response}
        if name:
            details["name"] = name

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


class BaseRAGReviewer(BaseReviewer):
    """RAG增强审查器基类"""

    def __init__(self, name: str, vector_store=None):
        super().__init__(name)
        self.vector_store = vector_store

    async def search_relevant_docs(self, content: str, top_k: int = 5) -> list:
        """
        搜索相关文档
        子类需要实现具体的检索逻辑
        """
        # 这里是占位实现，具体逻辑在子类中实现
        return []

    def get_enhanced_context(self, content: str, relevant_docs: list) -> str:
        """
        构建增强的上下文
        """
        context_parts = [
            "以下是相关的标准规范和案例：",
            ""
        ]

        for i, doc in enumerate(relevant_docs, 1):
            context_parts.append(f"{i}. {doc.get('content', '')}")
            if doc.get('source'):
                context_parts.append(f"   来源：{doc['source']}")
            context_parts.append("")

        return "\n".join(context_parts)