#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
内容单元拆分Agent

功能：将视频脚本拆解为L3单元（Units），并按照严格的"实质 × 形式"矩阵进行分析
"""

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, get_video_file_from_state

logger = get_logger(__name__)


class ContentUnitSplitAgent(BaseLLMAgent):
    """内容单元拆分Agent - 将视频脚本拆解为L3单元并进行实质×形式矩阵分析"""

    def __init__(
        self,
        name: str = "content_unit_split_agent",
        description: str = "内容单元拆分Agent - 将视频脚本拆解为L3单元并进行实质×形式矩阵分析",
        model_provider: str = "google_genai",
        temperature: float = 0.1,
        max_tokens: int = 40960
    ):
        """初始化内容单元拆分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 """你是一名精通传播学与视听语言的内容分析师，擅长对视频脚本进行微观层面的原子级解构。"""

    def process(self, state: Dict[str, Any], config=None) -> Dict[str, Any]:
        """处理状态 - 对视频脚本进行L3单元拆分和实质×形式分析（JSON 结构）

        Args:
            state: 包含视频文件的状态字典

        Returns:
            包含分析结果的字典，格式为（全部中文 key，便于后续解析）：
            {
                "content_unit_analysis": {
                    "单元列表": [
                        {
                            "单元编号": int,
                            "时间范围": str,
                            "单元核心概括": str,
                            "完整文案": str,
                            "实质": {
                                "具体元素": {...},
                                "具象概念": {...},
                                "抽象概念": {...}
                            }
                        },
                        ...
                    ]
                }
            }
        """
        if not self.is_initialized:
            self.initialize()

        logger.info("=" * 80)
        logger.info("内容单元拆分 (ContentUnitSplitAgent)")
        logger.info("=" * 80)

        try:
            # 从 state 中获取视频文件对象
            video_file = get_video_file_from_state(state)
            if not video_file:
                logger.warning("无法获取视频文件对象，跳过内容单元拆分分析")
                return {
                    "content_unit_analysis": {
                        "error": "无法获取视频文件对象",
                        "单元列表": []
                    }
                }

            # 构建分析提示词
            prompt = self._build_analysis_prompt()

            logger.info("开始视频脚本分析和L3单元拆分...")

            # 使用通用的 safe_invoke_video_analysis 进行视频分析
            result = LLMInvoker.safe_invoke_video_analysis(
                operation_name="内容单元拆分分析",
                video_file=video_file,
                prompt=prompt,
                agent=self,
                fallback={
                    "error": "视频分析返回空结果",
                    "单元列表": []
                }
            )

            # 期望 result 为已解析的 JSON 对象（dict），包含「单元列表」等中文 key
            if not isinstance(result, dict) or not result:
                logger.warning("视频分析返回结果为空或非字典，将返回降级结构")
                return {
                    "content_unit_analysis": {
                        "error": "视频分析返回空结果或解析失败",
                        "单元列表": []
                    }
                }

            unit_list = result.get("单元列表", [])
            logger.info(f"分析完成，单元数量: {len(unit_list)}")
            logger.info("=" * 80)

            return {
                "content_unit_analysis": result
            }

        except Exception as e:
            logger.error(f"内容单元拆分失败: {e}", exc_info=True)
            return {
                "content_unit_analysis": {
                    "error": str(e),
                    "单元列表": []
                }
            }

    def _build_analysis_prompt(self) -> str:
        """构建分析提示词（要求直接输出 JSON，全部中文 key）"""
        return """# Role
你是一名精通传播学与视听语言的内容分析师，擅长对视频脚本进行微观层面的原子级解构。

# Task
请阅读我提供的视频，将其拆解为一个个独立的「L3 单元（Units）」，并按照严格的「实质 × 形式」矩阵进行分析，并**以 JSON 结构输出结果（全部使用中文 key）**。

# Definitions
1.  **L3 单元 (Unit)**：视频中最小的语义单位，通常是一个完整的句子或一个短语意群。
2.  **实质 (Substance)**：单元内容所包含的信息内核，分为三层：
    - 实质A-具体元素：人、物、地名、数据等实体。
    - 实质B-具象概念：动作、状态、反应、感官体验等。
    - 实质C-抽象概念：价值观、情绪、地位、评价等。

3.  **形式 (Form)**：承载实质的表现手段，分为三维：
    - 文案形式：修辞、句式、语态、词汇选择。
    - 画面形式：景别、色彩、构图、字幕特效、运镜（若脚本未提及，请根据文案逻辑合理推断常规操作）。
    - 声音形式：语速、语调、BGM情绪、音效（若脚本未提及，请根据文案逻辑合理推断）。

# Constraints
- **必须严格对应**：分析「具体元素」时只能谈论呈现该元素的形式，不可混淆。
- **完整性**：覆盖脚本的每一秒，不要遗漏任何信息。
- **客观性**：形式分析必须基于视听语言学，而非主观臆测。

# Workflow
1.  按时间顺序切分脚本。
2.  逐个单元填写解构表。

# Output Format (JSON)
请最终只输出一个 JSON 对象，**全部使用中文 key**，结构示例如下（可根据实际需要增减字段，但需保持语义清晰、便于解析）：

{
  "单元列表": [
    {
      "单元编号": 1,
      "时间范围": "00:00-00:05",
      "单元核心概括": "本单元在讲的核心意思简要概括",
      "完整文案": "该单元对应的完整字幕或口播文案",
      "实质": {
        "具体元素": {
          "关键词": ["人物A", "地点B", "物品C"],
          "对应形式": {
            "文案形式": "针对具体元素的文案表现分析",
            "画面形式": "针对具体元素的画面表现分析",
            "声音形式": "针对具体元素的声音表现分析"
          }
        },
        "具象概念": {
          "关键词": ["动作D", "状态E"],
          "对应形式": {
            "文案形式": "针对具象概念的文案表现分析",
            "画面形式": "针对具象概念的画面表现分析",
            "声音形式": "针对具象概念的声音表现分析"
          }
        },
        "抽象概念": {
          "关键词": ["情绪F", "价值观G"],
          "对应形式": {
            "文案形式": "针对抽象概念的文案表现分析",
            "画面形式": "针对抽象概念的画面表现分析",
            "声音形式": "针对抽象概念的声音表现分析"
          }
        }
      }
    }
  ]
}

要求：
- 只输出一个 JSON 对象，不要输出任何其他说明文字。
- 所有字段名必须是中文（如：单元列表、时间范围、完整文案、具体元素、文案形式 等）。
- 确保 JSON 语法合法，便于程序直接解析和使用。"""

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

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