#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
金句提取Agent（视频分析版本）

功能:
1. 从 state 中读取视频文件对象
2. 使用 Gemini 视频分析能力，直接基于视频内容提取"钩子"和"金句"
"""

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 ScriptKeywordAgent(BaseLLMAgent):
    """金句提取Agent - 基于视频分析提取钩子和金句"""

    def __init__(
        self,
        name: str = "script_keyword_agent",
        description: str = "金句提取Agent - 直接基于视频内容提取钩子和金句",
        model_provider: str = "google_genai",
        temperature: float = 0.4,
        max_tokens: int = 20480,
    ):
        # 这里的 system_prompt 仅用于初始化模型（提供 model_name），
        # 实际的视频分析逻辑全部通过 safe_invoke_video_analysis 的 prompt 控制
        system_prompt = "你是一名专注于中国60岁+老年群体短视频生态的内容分析专家。"
        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("金句提取Agent开始执行")

        # Step 0: 从 state 中获取视频文件对象
        video_file = get_video_file_from_state(state)
        if not video_file:
            logger.warning("无法获取视频文件对象，跳过金句提取")
            return {
                "script_keywords": {
                    "error": "无法获取视频文件对象",
                },
            }

        try:
            # 直接基于视频内容进行金句提取
            logger.info("基于视频内容进行金句提取...")
            keyword_prompt = self._build_keyword_prompt()

            keyword_result = LLMInvoker.safe_invoke_video_analysis(
                "金句提取(钩子和金句)",
                video_file,
                keyword_prompt,
                agent=self,
                fallback={
                    "script_type": "",
                    "hooks": [],
                    "golden_sentences": [],
                },
            )

            logger.info("金句提取Agent执行完成")

            return {
                "script_keywords": keyword_result,
            }

        except Exception as e:
            logger.error(f"金句提取Agent执行失败: {e}", exc_info=True)
            return {
                "script_keywords": {
                    "error": str(e),
                },
            }

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

    def _build_keyword_prompt(self) -> str:
        """构建基于视频内容的金句提取 Prompt"""
        return """
# Role
你是一名专注于中国 60岁+ 老年群体短视频生态的内容分析专家。你的核心能力是识别视频脚本中的"传播基因"和"心理抓手"。

# Task
请根据视频，利用【认知缺口】和【高能评判】两大底层逻辑，提取脚本中的"钩子（Hooks）"和"金句（Golden Sentences）"。

# Extraction Rules (必须严格遵守)
## 1. 场景预判 (Scenario Detection)
首先判断脚本属于以下哪种类型，并调整提取侧重：
- **类型 A：叙事/人物/科普类**（如名人故事、大国重器）
  -> 侧重提取：核心冲突、悲情叙事、民族情绪、正名/喊冤。
- **类型 B：盘点/猎奇/生活类**（如奇葩村庄、顺口溜、养生）
  -> 侧重提取：反常识特征、极低成本获益、顺口溜韵脚。

## 2. 定义与提取「钩子」(The Hooks)
*目标：提取制造悬念、打破常识或直击痛点的短句（用于留存）。*

请扫描脚本开头及段落转折处，提取符合以下逻辑的句子：
1.  **逻辑悬空 (The Open Loop):** 展示了惊人的结果或高唤醒度的状态，但隐去了原因或过程。（例如："看完才明白他的良苦用心"、"99%的人都不知道"）
2.  **反常识特征 (The Strange Feature):** 描述违背常理、伦理或物理规律的现象。**注意：将具体的生僻地名/人名抽象为特征描述。**（例如："男人一辈子只能生活在树上"、"娶媳妇只需要一头猪"）
3.  **痛点与利益 (Pain & Benefit):** 直接针对健康、养老金、子女关系的强引导。（例如："千万别再这样吃"、"过了60岁要注意"）

## 3. 定义与提取「金句」(The Golden Sentences)
*目标：提取用于社交货币、情绪宣泄或身份认同的短句（用于分享）。*
请扫描全文（特别是结尾和高潮处），提取符合以下逻辑的句子：
1.  **绝对化定性 (Absolute Judgment):** 脱离具体时空叙事，对人/事/物进行盖棺定论的总结。包含"一辈子"、"凡是"、"绝对"、"就是"等词。（例如："手里有钱才是硬道理"、"他一辈子就做了一件事"）
2.  **核心冲突与宣泄 (Conflict & Venting):** 描述 [付出 vs 误解]、[高尚 vs 庸俗]、[我们 vs 敌人] 的强烈对比。包含"嘲讽"、"心寒"、"咬牙切齿"、"不再看脸色"等词。（例如："把一生献给国家的科学家被人误解多年"）
3.  **乌托邦与治愈 (The Utopia):** 描绘老年人向往的理想状态，或否定现实压力。（例如："没有复杂的婆媳关系"、"把老年变玩年"）
4.  **韵律与警世 (Rhymes):** 押韵的顺口溜或具有视觉冲击力的警世格言。（例如："饭再好没有牙，钱再多床上趴"）

## 4. 负面清单 (Negative List - 不要提取)
- **纯事实叙事：** 具体的年份、复杂的数字、毫无特征的流水账（如"1996年他去了北京"）。
- **主播口水话：** "点好关注"、"屏幕前的朋友"、"您收到了吗"。
- **长难句：** 如果句子超过 30 字且无法拆解出独立观点，请忽略。
- **无意义连接词：** "话说"、"那么"、"之所以"。

# Output Format (JSON)
请直接输出 JSON 格式数据，不要包含任何解释性文字。
{
  "script_type": "判断是 类型A 或 类型B",
  "hooks": [
    "提取的钩子1",
    "提取的钩子2 (必须保留原文语气，如'竟然'、'千万')"
  ],
  "golden_sentences": [
    "提取的金句1",
    "提取的金句2",
    "提取的金句3 (必须是完整的观点或情绪表达)"
  ]
}
""".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
