#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
选题结构Agent V2（视频分析版本）

功能:
1. 从 state 中读取视频文件对象
2. 使用 Gemini 视频分析能力，直接基于视频内容按照"老年人微信分享回流"选题解构 Prompt，
   生成结构化选题 JSON
"""

from typing import Any, Dict

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 TopicAgentV2(BaseLLMAgent):
    """选题结构Agent V2 - 基于视频分析直接进行选题结构分析"""

    def __init__(
        self,
        name: str = "topic_agent_v2",
        description: str = "选题结构Agent V2 - 直接基于视频内容进行老年人选题结构分析",
        model_provider: str = "google_genai",
        temperature: float = 0.4,
        max_tokens: int = 20480,
    ):
        # 这里的 system_prompt 仅用于初始化模型（提供 model_name），
        # 实际的视频分析逻辑全部通过 safe_invoke_video_analysis 的 prompt 控制
        system_prompt = "你是一个视频内容分析助手，用于进行选题结构化分析。"
        super().__init__(
            name=name,
            description=description,
            model_provider=model_provider,
            system_prompt=system_prompt,
            temperature=temperature,
            max_tokens=max_tokens,
        )

    # ==================== 对外主入口 ====================

    def process(self, state: Dict[str, Any], config=None) -> Dict[str, Any]:
        """处理状态

        步骤：
        1. 从 state 中读取视频文件对象
        2. 直接调用 safe_invoke_video_analysis，基于视频内容做选题结构分析
        3. 将选题结构结果写回 state
        """
        if not self.is_initialized:
            self.initialize()

        logger.info("选题结构AgentV2开始执行")

        # Step 0: 从 state 中获取视频文件对象
        video_file = get_video_file_from_state(state)
        if not video_file:
            logger.warning("无法获取视频文件对象，跳过选题结构分析")
            return {
                "video_script": "",
                "topic_selection_v2": {
                    "error": "无法获取视频文件对象",
                },
            }

        try:
            # 直接基于视频内容进行老年人选题结构分析
            logger.info("基于视频内容进行老年人选题结构分析...")
            topic_prompt = self._build_topic_prompt()

            topic_result = LLMInvoker.safe_invoke_video_analysis(
                "选题结构分析(老年人微信分享回流)",
                video_file,
                topic_prompt,
                agent=self,
                fallback={
                    "选题": {
                        "选题点": {
                            "利益点": [],
                            "社交点": {},
                        },
                        "关键点": {
                            "实体": [],
                            "圈层": [],
                        },
                        "选题结构": {
                            "一句话综述": "",
                        },
                    }
                },
            )

            logger.info("选题结构AgentV2执行完成")

            return {
                "video_script": "",
                "topic_selection_v2": topic_result,
            }

        except Exception as e:
            logger.error(f"选题结构AgentV2执行失败: {e}", exc_info=True)
            return {
                "video_script": "",
                "topic_selection_v2": {
                    "error": str(e),
                },
            }

    # ==================== Prompt 构建 ====================

    def _build_topic_prompt(self) -> str:
        """构建基于视频内容的老年人选题结构分析 Prompt"""
        return """
# Role
你是一名专注于中国老年人内容消费行为与微信生态传播机制的资深内容分析师。你服务于一个针对60岁以上人群的视频平台，你的核心任务是通过解构视频内容，提取出能够用于"精准搜索"和"爆款判断"的结构化数据。

# Goal
请仔细观看我提供的【视频内容】，基于"老年人微信分享回流"的业务逻辑，按照【解构模型】的要求，精准提取选题信息。输出结果必须严格遵守JSON格式。

# 关键约束
1. **只能根据视频中的画面、解说、环境音、人物对话来分析内容**。
2. **禁止**把画面上的任何文字内容（如字幕、贴片文案、标题、弹幕、备注说明等）作为主要依据。如果画面中出现文字，只能通过**描述该画面的含义或功能**来理解，而不是逐字记录文字内容。
3. 必须基于视频的实际内容进行分析，不能凭空臆造。

# Context & Logic
1.  用户画像：60岁以上中国老年人。他们关注健康、家庭、爱国、怀旧、省钱，容易受情绪感染，喜欢在微信群/朋友圈分享以获得社交认同。
2.  业务目标：
    *   搜索（去哪找）：需要提取视频内容中最具体的实体名词。
    *   判断（会不会火）：需要判断视频提供了什么功利性价值（利益点）以及触发了什么转发动机（社交点）。

# Deconstruction Model (解构模型标准)
请严格按照以下四个维度进行提取：
## 1. 关键点 (The Atoms) —— 用于生成搜索关键词
*   实体 (Entities)：视频中讨论的最具体、最核心的客观名词。
    *   要求：必须是视频中真实存在的、可被名词化的对象。优先提取人名、地名、特定物品、特定政策、专有名词、对立实体（如"明星绯闻"）。
    *   反例：不要提取"精彩"、"感动"这种形容词。
*   圈层 (Circle)：视频显性或隐性圈定的目标人群身份标签。
    *   要求：思考"谁最会在微信群里点开这个视频？"（如：退休人员、爱国退伍军人、带孙子的奶奶、高血压患者）。

## 2. 选题点 (The Value & Driver) —— 用于判断爆款潜力
*   利益点 (Benefit)：用户看完视频能得到的直接获得感。
    *   思考维度：避坑止损（防骗/防病）、获得收益（省钱/长寿）、获取新知（猎奇/政策）、情绪抚慰（怀旧/感动）、娱乐消遣（看热闹）。
    *   格式：[价值类型] + 具体描述。
*   社交点 (Social Trigger)：用户将视频分享到微信群/朋友圈的深层动力。
    *   思考维度：
        *   预警货币：紧急通知亲友防灾/避坑。
        *   关怀货币：表达对子女/老友的问候与关心。
        *   谈资货币：展示自己博学、见多识广、消息灵通。
        *   嘴替货币：借视频表达自己说不出口的态度或情感。
        *   捍卫者货币：通过转发来表达价值观站位（如爱国、反感娱乐圈），通过"拉踩"获得道德优越感。
        *   施压型货币：视频中含有"不转不是中国人"、"别在你手里断了"等道德绑架或祈福暗示。
    *   格式：[货币类型] + 具体描述。

## 3. 选题结构 (The Synthesis)
*   一句话综述：将上述元素有机组合。
    *   模板：这是一条面向【圈层】的，关于【实体】的视频，提供了【利益点】，具备【社交点】属性。

# Constraint (约束)
1.  **客观性**：提取的实体必须源于视频内容，不能凭空臆造。
2.  **具体化**：利益点和社交点必须结合视频内容具体描述，不能只写"有价值"或"想分享"。
3.  **格式**：输出必须为纯粹的JSON格式，不要包含Markdown代码块标记（```json）之外的任何解释性文字。

# Workflow
1.  仔细观看视频，识别核心谈论对象（实体）。
2.  分析视频的语气和内容，画像目标受众（圈层）。
3.  代入老年用户视角，分析我为什么看（利益），我为什么转（社交）。
4.  按照JSON格式输出。

# Output Format (JSON)

请只返回以下 JSON 结构，本身就是一个合法的 JSON，对象外部不要添加任何解释、前后缀或 Markdown 代码块：

{
  "选题": {
    "选题点": {
      "利益点": {
        "类型": "具体描述",
        "类型": "具体描述",
      },
      "社交点": {
        "货币类型": "具体描述",
        "货币类型": "具体描述",
      }
    },
    "关键点": {
      "实体": [
        "实体1",
        "实体2",
        "实体3"
      ],
      "圈层": [
        "人群1",
        "人群2"
      ]
    },
    "选题结构": {
      "一句话综述": "内容综述"
    }
  }
}
""".strip()

    # ==================== BaseLLMAgent 抽象方法占位实现 ====================

    def _build_messages(self, state: Dict[str, Any]) -> list:
        """满足 BaseLLMAgent 抽象要求（本 Agent 不通过该路径调用）"""
        return []

    def _update_state(self, state: Dict[str, Any], response: Any) -> Dict[str, Any]:
        """满足 BaseLLMAgent 抽象要求（本 Agent 不通过该路径调用）"""
        return state
