#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
脚本段落划分Agent

功能: 分析视频的分段结构，理解创作者是如何组织内容的（创作者视角）
输出: 段落列表（树状结构）
"""

from typing import List, Dict, Any
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 ScriptSectionDivisionAgent(BaseLLMAgent):
    """脚本段落划分Agent - 分析视频的分段结构（创作者视角）
    """

    def __init__(
        self,
        name: str = "script_section_division_agent",
        description: str = "脚本段落划分Agent - 分析视频的分段结构（创作者视角）",
        model_provider: str = "google_genai",
        temperature: float = 0.1,
        max_tokens: int = 40960
    ):
        """初始化脚本段落划分Agent
        """
        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. 树状输出：通过子项字段表示层级关系，不使用parent_id

# 工作原则
- 识别创作者如何分段组织视频内容（树状结构）
- 需要对视频进行逐帧或关键帧分析，捕捉画面、动作、场景、对话等维度的结构变化"""

    def process(self, state: Dict[str, Any], config=None) -> Dict[str, Any]:
        """处理state，执行段落划分

        从state中提取视频文件，执行段落划分，并返回结果

        Args:
            state: 工作流状态，包含视频文件对象

        Returns:
            dict: 包含段落列表和内容品类
        """
        if not self.is_initialized:
            self.initialize()

        logger.info("=== 开始脚本段落划分 ===")

        # 从state中获取视频文件对象
        video_file = get_video_file_from_state(state)

        if not video_file:
            logger.warning("无法获取视频文件对象，跳过段落划分")
            return {
                "内容品类": "未知品类",
                "段落列表": []
            }

        # 执行段落划分
        logger.info("执行段落划分")
        result = self._divide_sections(video_file)

        # 只打印JSON结构
        import json
        logger.info(f"段落划分结果:\n{json.dumps(result, ensure_ascii=False, indent=2)}")

        return result

    def _divide_sections(self, video_file) -> dict:
        """段落划分
        分析视频内容，识别创作者是如何分段组织内容的
        """
        logger.info("【段落划分】分析视频的分段结构")

        # 构建用户prompt
        user_prompt = """# 任务

从**创作者视角**分析这个视频是如何组织内容的。

## Section切分流程

**第一步：识别主题显著变化位置**
扫描整个视频,识别**主题发生显著变化**的位置:

- **判断标准**:
  * 语义跃迁: 讨论对象发生根本性改变
  * 逻辑转换: 从"是什么"转向"为什么"或"怎么办"
  * 功能变化: 从"问题陈述"转向"解决方案"
  * 场景切换: 画面、场景、动作发生明显变化
  * 对话转换: 话题、语气、情绪发生明显变化

- **划分原则**:
  * 避免过度细分(每个小变化都成为顶层段落)
  * 避免过度粗放(将所有内容合并为1个顶层段落)
  * 以"主题板块"而非"内容单元"为划分粒度

**第二步：初步划分**
- 基于主题显著变化位置进行划分
- 支持主Section和子Section的层级结构
- 需要对视频进行逐帧或关键帧分析，捕捉画面、动作、场景、对话等维度的结构变化

**第三步：顺序验证与反思**
- 检查每个Section内的视频片段是否保持时间顺序的连续性
- 验证同一Section内的内容是否有语义关联
- 确认段落之间的过渡是否自然合理

## 层级要求

**段落必须至少保留2层结构**：
1. **第1层（抽象层）**：从具象中聚合出的共性维度
2. **第2层（具象层）**：具体的内容细节

**层级关系说明**：
- 抽象层是对多个具象内容的归纳和提炼
- 具象层是抽象层的具体展开
- 每个抽象层下必须有至少1个具象层子项

## Section字段

- 描述: 段落描述（共性维度名称；具体内容概括）
- 内容范围: **列表格式，包含具体视频片段**
  - 格式：["0:00-0:30", "0:30-1:15"] 或 ["片段1: 开场介绍", "片段2: 问题阐述"]
  - 要求：必须包含具体的时间戳范围或视频片段描述，清晰标识该Section涵盖的视频内容
- 推理依据: 为什么这样划分
- 子项: 子Section列表（树状结构）

# 输出（JSON）- 树状结构

{
  "内容品类": "内容品类",
  "段落列表": [
    {
      "描述": "共性维度名称",
      "内容范围": ["0:00-0:30", "0:30-1:15"],
      "推理依据": "为什么这样划分这个抽象层",
      "子项": [
        {
          "描述": "具体内容概括",
          "内容范围": ["0:00-0:30"],
          "推理依据": "这个具象内容如何支撑上层抽象",
          "子项": []
        }
      ]
    }
  ]
}"""

        # 合并system_prompt和user_prompt
        full_prompt = f"""{self.system_prompt}

{user_prompt}"""

        # 调用LLM进行视频分析
        result = LLMInvoker.safe_invoke_video_analysis(
            operation_name="Section划分",
            video_file=video_file,
            prompt=full_prompt,
            agent=self,
            fallback={"内容品类": "未知品类", "段落列表": []}
        )

        # 为每个段落生成唯一ID
        sections_with_id = self._add_section_ids(result.get("段落列表", []))
        result["段落列表"] = sections_with_id

        # 只打印JSON结构
        import json
        logger.info(f"段落划分详细结果:\n{json.dumps(result, ensure_ascii=False, indent=2)}")

        return result

    def _add_section_ids(self, sections: list, parent_prefix: str = "") -> list:
        """递归为段落添加唯一ID

        Args:
            sections: 段落列表
            parent_prefix: 父级前缀（用于生成层级ID）

        Returns:
            list: 添加了ID的段落列表
        """
        result = []
        for idx, section in enumerate(sections, 1):
            # 生成当前段落ID
            if parent_prefix:
                section_id = f"{parent_prefix}.{idx}"
            else:
                section_id = f"段落{idx}"

            # 添加ID字段
            section_with_id = {
                "id": section_id,
                **section
            }

            # 递归处理子项
            if section.get("子项"):
                section_with_id["子项"] = self._add_section_ids(
                    section["子项"],
                    section_id
                )

            result.append(section_with_id)

        return result

    def _build_messages(self, state: dict) -> List[dict]:
        """构建消息 - ScriptSectionDivisionAgent 不使用此方法

        本 Agent 使用 _divide_sections 方法直接构建消息
        """
        return []

    def _update_state(self, state: dict, response) -> dict:
        """更新状态 - ScriptSectionDivisionAgent 不使用此方法

        本 Agent 使用 _divide_sections 方法直接返回结果
        """
        return state
