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


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):
        self.model_client = generate_model_client
        self.prompt_loader = prompt_loader
    
    # @obverse
    async def review(self, name: str, trace_id: str, reviewer_type: str, prompt_name: str, review_content: str,review_references: 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: 审查参考内容 (可选)

        Returns:
            ReviewResult: 审查结果
        """
        start_time = time.time()
        name = prompt_name
        try:
            logger.info(f"开始执行 {name} 审查，trace_id: {trace_id},内容长度: {len(review_content)}")
            prompt_kwargs = {}
            prompt_kwargs["content"] = review_content
            prompt_kwargs["review_content"] = review_content
            prompt_kwargs["review_references"] = review_references or ""
            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)
            result.execution_time = time.time() - start_time

            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) -> ReviewResult:
        """
        格式化模型返回结果为ReviewResult对象
        """
        return ReviewResult(
            success=True,
            details={"response": model_response},
            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)