#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
内容权重判断Agent

功能：判断帖子中图片和文字哪个权重更高，为后续灵感点提取提供指导
"""

from typing import Any, Dict, List

from src.components.agents.base import BaseLLMAgent
from src.utils.logger import get_logger
from src.utils.llm_invoker import LLMInvoker

logger = get_logger(__name__)


class ContentWeightAgent(BaseLLMAgent):
    """内容权重判断Agent - 判断图片和文字的权重分配及图文关系

    输出格式：
    {
        "image_weight": 0-10的整数（图片权重分数）,
        "text_weight": 0-10的整数（文字权重分数）,
        "weight_difference": "明显图片为主" | "明显文字为主" | "权重相近",
        "primary_source": "image" | "text" | "both",
        "content_relationship": "相关" | "不相关",
        "analysis": "详细的权重判断说明"
    }
    """

    def __init__(
        self,
        name: str = "content_weight_agent",
        description: str = "内容权重判断Agent - 判断图片和文字的权重分配",
        model_provider: str = "google_genai",
        temperature: float = 0.3,  # 较低温度，要求客观判断
        max_tokens: int = 20480
    ):
        """
        初始化内容权重判断Agent

        Args:
            name: Agent名称
            description: Agent描述
            model_provider: 模型提供商
            temperature: 生成温度（较低，保证客观性）
            max_tokens: 最大token数
        """
        system_prompt = self._build_system_prompt()
        super().__init__(
            name=name,
            description=description,
            model_provider=model_provider,
            system_prompt=system_prompt,
            temperature=temperature,
            max_tokens=max_tokens
        )

    def _build_system_prompt(self) -> str:
        """构建系统提示词"""
        return """你是内容权重分析专家，专门判断帖子中图片和文字哪个权重更高，以及图文之间的关系。

# 核心任务
1. 从创作者视角分析：这个帖子的核心信息承载在图片还是文字？
2. 判断图文关系：图片和文字是相关的还是不相关的？

# 判断维度

## 1. 信息量维度（0-10分）
- **图片信息量**：图片承载了多少独特信息？
  - 纯展示性图片（如单纯的产品图、自拍）：2-4分
  - 场景丰富、细节多的图片（如旅游风景、复杂场景）：5-7分
  - 信息密集型图片（如图表、对比图、教程图）：8-10分

- **文字信息量**：文字承载了多少独特信息？
  - 简短标题或标签：2-4分
  - 中等长度描述性文字：5-7分
  - 详细的说明、故事、教程：8-10分

## 2. 独立理解性（0-10分）
- **图片独立性**：不看文字，仅看图片能理解多少内容？
  - 完全无法理解主题：0-3分
  - 能理解部分内容但缺少关键信息：4-6分
  - 能完整理解核心内容：7-10分

- **文字独立性**：不看图片，仅看文字能理解多少内容？
  - 完全无法理解主题：0-3分
  - 能理解部分内容但缺少关键信息：4-6分
  - 能完整理解核心内容：7-10分

## 3. 核心价值承载（0-10分）
- **图片核心价值**：帖子的核心吸引力、核心观点、核心创意是否体现在图片中？
  - 图片只是装饰：0-3分
  - 图片提供重要支持但非核心：4-6分
  - 图片承载核心价值：7-10分

- **文字核心价值**：帖子的核心吸引力、核心观点、核心创意是否体现在文字中？
  - 文字只是描述：0-3分
  - 文字提供重要支持但非核心：4-6分
  - 文字承载核心价值：7-10分

# 评分计算
- **图片权重** = (图片信息量 + 图片独立性 + 图片核心价值) / 3（四舍五入到整数）
- **文字权重** = (文字信息量 + 文字独立性 + 文字核心价值) / 3（四舍五入到整数）

# 权重差异判定
- **明显图片为主**：图片权重 - 文字权重 >= 3
- **明显文字为主**：文字权重 - 图片权重 >= 3
- **权重相近**：|图片权重 - 文字权重| < 3

# 主要信息源判定
- **image**（图片为主）：图片权重 > 文字权重 + 2
- **text**（文字为主）：文字权重 > 图片权重 + 2
- **both**（都重要）：|图片权重 - 文字权重| <= 2

# 图文关系判定
判断图片和文字之间是"相关"还是"不相关"：

## 相关的判定标准
- 图文描述同一主题/对象
- 图文相互补充、相互解释
- 文字是对图片的说明，或图片是对文字的展示

## 不相关的判定标准
- 图文描述不同主题/对象
- 图片和文字分别承载独立的信息，没有相互解释的关系

# 分析原则
- 客观评估，基于实际内容而非主观偏好
- 考虑创作者意图：TA想通过图片还是文字传达核心信息？
- 考虑受众视角：用户主要从图片还是文字获取价值？
- 仔细判断图文关系：不能仅凭权重，还要看图文是否相关"""

    def process(self, state: Dict[str, Any], config=None) -> Dict[str, Any]:
        """处理状态 - 判断图片和文字权重

        Args:
            state: 包含 text（文字数据）和 images（图片URL列表）

        Returns:
            权重判断结果
        """
        if not self.is_initialized:
            self.initialize()

        logger.info("=" * 80)
        logger.info("内容权重判断 (ContentWeightAgent)")
        logger.info("=" * 80)

        try:
            text_data = state.get("text", {})
            images = state.get("images", [])

            # 构建提示词
            prompt = self._build_weight_judgment_prompt(text_data, images)

            # 构建多模态消息
            message_content = [{"type": "text", "text": prompt}]

            # 添加图片
            if images:
                for idx, image_path in enumerate(images, 1):
                    message_content.append({"type": "text", "text": f"[图片{idx}]"})
                    message_content.append({
                        "type": "image_url",
                        "image_url": {"url": image_path}
                    })

            messages = [
                {"role": "system", "content": self.system_prompt},
                {"role": "user", "content": message_content}
            ]

            # 调用LLM
            result = LLMInvoker.safe_invoke(
                self,
                "内容权重判断",
                messages,
                fallback={
                    "image_weight": 5,
                    "text_weight": 5,
                    "weight_difference": "权重相近",
                    "primary_source": "both",
                    "content_relationship": "相关",
                    "analysis": "权重判断失败，默认图片和文字同等重要，图文相关"
                }
            )

            logger.info(f"权重判断结果: 图片={result.get('image_weight', 0)}, "
                       f"文字={result.get('text_weight', 0)}, "
                       f"主要信息源={result.get('primary_source', 'both')}")
            logger.info(f"权重差异: {result.get('weight_difference', '未知')}")
            logger.info(f"图文关系: {result.get('content_relationship', '未知')}")
            logger.info(f"分析说明: {result.get('analysis', '')}")
            logger.info("=" * 80)

            return {
                "content_weight": result
            }

        except Exception as e:
            logger.error(f"内容权重判断失败: {e}", exc_info=True)
            return {
                "content_weight": {
                    "image_weight": 5,
                    "text_weight": 5,
                    "weight_difference": "权重相近",
                    "primary_source": "both",
                    "content_relationship": "相关",
                    "analysis": f"权重判断失败: {str(e)}，默认图片和文字同等重要，图文相关",
                    "error": str(e)
                }
            }

    def _build_weight_judgment_prompt(
        self,
        text_data: Dict[str, Any],
        images: List[str]
    ) -> str:
        """构建权重判断提示词"""

        # 构建文字摘要
        text_parts = []
        if text_data.get("title"):
            text_parts.append(f"标题: {text_data['title']}")
        if text_data.get("body"):
            text_parts.append(f"正文: {text_data['body']}")
        if text_data.get("hashtags"):
            text_parts.append(f"话题标签: {' '.join(text_data['hashtags'])}")

        text_summary = "\n".join(text_parts) if text_parts else "无文字内容"

        # 图片信息
        image_info = f"图片数量: {len(images)}张" if images else "无图片"

        prompt = f"""# 任务：判断图片和文字的权重

## 帖子内容

### 文字内容
{text_summary}

### 图片内容
{image_info}
{'（图片将在后续消息中提供）' if images else ''}

## 分析要求

请按照以下步骤进行分析：

### 第一步：分维度评分（每个维度0-10分）

**图片评分**：
1. 信息量（0-10）：图片承载了多少独特信息？
2. 独立理解性（0-10）：不看文字，仅看图片能理解多少内容？
3. 核心价值承载（0-10）：帖子的核心吸引力、核心观点、核心创意是否体现在图片中？

**文字评分**：
1. 信息量（0-10）：文字承载了多少独特信息？
2. 独立理解性（0-10）：不看图片，仅看文字能理解多少内容？
3. 核心价值承载（0-10）：帖子的核心吸引力、核心观点、核心创意是否体现在文字中？

### 第二步：计算权重
- **图片权重** = (图片信息量 + 图片独立性 + 图片核心价值) / 3（四舍五入）
- **文字权重** = (文字信息量 + 文字独立性 + 文字核心价值) / 3（四舍五入）

### 第三步：判定权重差异
- 图片权重 - 文字权重 >= 3 → "明显图片为主"
- 文字权重 - 图片权重 >= 3 → "明显文字为主"
- |图片权重 - 文字权重| < 3 → "权重相近"

### 第四步：确定主要信息源
- 图片权重 > 文字权重 + 2 → "image"
- 文字权重 > 图片权重 + 2 → "text"
- 其他情况 → "both"

### 第五步：判断图文关系
判断图片和文字是"相关"还是"不相关"：
- **相关**：图文描述同一主题/对象，相互补充解释
- **不相关**：图文描述不同主题，或图片是成果展示而文字是过程说明

## 输出格式（JSON）
```json
{{
  "dimension_scores": {{
    "image": {{
      "information_volume": 8,
      "independence": 7,
      "core_value": 9
    }},
    "text": {{
      "information_volume": 5,
      "independence": 6,
      "core_value": 4
    }}
  }},
  "image_weight": 8,
  "text_weight": 5,
  "weight_difference": "明显图片为主",
  "primary_source": "image",
  "content_relationship": "相关",
  "analysis": "详细说明为什么得出这个判断，包括：\\n1. 图片的信息承载情况\\n2. 文字的信息承载情况\\n3. 两者的配合关系\\n4. 核心信息主要来源\\n5. 图文关系判断依据"
}}
```

**重要**：
- 必须客观评分，基于实际内容
- analysis字段必须详细说明判断理由
- 所有评分都是0-10的整数"""

        return prompt

    def _build_messages(self, state: Dict[str, Any]) -> List[Dict[str, Any]]:
        """构建消息 - ContentWeightAgent 在 process 方法中直接构建消息"""
        return []

    def _update_state(self, state: Dict[str, Any], response: Any) -> Dict[str, Any]:
        """更新状态 - ContentWeightAgent 在 process 方法中直接返回结果"""
        return state
