"""
Result Aggregation Function（视频分析版本）

结果汇总函数：将所有解构结果汇总为最终的JSON结构，包括三点解构（灵感点、目的点、关键点）、选题理解和搜索关键词。
视频分析版本：不包含元素树，只汇总三点解构、选题理解和搜索关键词结果。
"""

from typing import Dict, Any, List, Optional

from src.components.functions.base import BaseFunction
from src.states.what_deconstruction_state import WhatDeconstructionState, ElementNode, FinalOutput
from src.utils.logger import get_logger

logger = get_logger(__name__)


class ResultAggregationFunction(BaseFunction[WhatDeconstructionState, Dict[str, Any]]):
    """结果汇总函数（视频分析版本）

    功能：
    - 将各Agent的解构结果组装为JSON结构
    - 汇总三点解构结果（灵感点、目的点、关键点）
    - 汇总选题理解结果
    - 汇总搜索关键词结果
    - 验证JSON格式

    注意：视频分析版本不包含元素树构建功能
    """

    def __init__(
        self,
        name: str = "result_aggregation_function",
        description: str = "汇总所有解构结果为最终的树状JSON结构（包括三点解构、选题理解和搜索关键词）"
    ):
        super().__init__(name, description)

    def execute(
        self,
        input_data: WhatDeconstructionState,
        context: Optional[Dict[str, Any]] = None
    ) -> Dict[str, Any]:
        """执行结果汇总

        Args:
            input_data: 工作流状态，包含所有解构结果
            context: 上下文信息

        Returns:
            最终的树状JSON结构
        """
        try:
            # 视频分析版本：仅提取视频相关结果
            video_url = input_data.get("video", "")
            
            # 从 state 中获取标题和正文（优先从直接字段获取，兼容text字典）
            title = input_data.get("title", "")
            body_text = input_data.get("body_text", "")
            if not title or not body_text:
                text_data = input_data.get("text", {})
                title = title or text_data.get("title", "")
                body_text = body_text or text_data.get("body", "")

            # 提取三点解构结果
            inspiration_points = input_data.get("inspiration_points", {})
            purpose_point = input_data.get("purpose_point", {})
            key_points = input_data.get("key_points", {})

            # 提取选题理解结果
            topic_selection_understanding = input_data.get("topic_selection_understanding", {})

            # 提取搜索关键词结果
            search_keywords = input_data.get("search_keywords", {})

            # 构建视频基本信息
            video_info = {
                "视频URL": video_url,
                "标题": title,
                "正文": body_text
            }

            # 组装最终JSON（视频分析版本）
            final_result: FinalOutput = {
                "视频信息": video_info,
                "三点解构": {
                    "灵感点": inspiration_points,
                    "目的点": purpose_point,
                    "关键点": key_points
                },
                "选题理解": topic_selection_understanding,
                "搜索关键词": search_keywords
            }

            # 验证JSON格式
            self._validate_result(final_result)

            search_keywords_count = search_keywords.get("总数", 0)
            logger.info(f"结果汇总完成（视频分析）：三点解构 + 选题理解 + 搜索关键词（{search_keywords_count}个）")

            return final_result

        except Exception as e:
            logger.error(f"结果汇总失败: {e}", exc_info=True)
            # 返回错误结果
            return {
                "视频信息": {},
                "三点解构": {
                    "灵感点": {},
                    "目的点": {},
                    "关键点": {}
                },
                "选题理解": {},
                "搜索关键词": {
                    "搜索词列表": [],
                    "总数": 0
                }
            }

    def _build_element_tree(
        self,
        id: str,
        result: Dict[str, Any],
        element_type: str
    ) -> ElementNode:
        """递归构建元素树（视频分析版本中不再使用，保留以保持代码完整性）

        Args:
            id: 节点ID
            result: 解构结果
            element_type: 元素类型（image/text）

        Returns:
            元素节点
        """
        element: ElementNode = {
            "id": id,
            "what": result.get("what", ""),
            "position": result.get("position", ""),  # 添加position字段
            "split_dimension": result.get("split_dimension", ""),  # 添加split_dimension字段
            "描述": result.get("description", result.get("描述", {})),
            "子节点元素关系": result.get("relationships", result.get("子节点元素关系", [])),
            "元素重要性权重": result.get("importance_weight", result.get("元素重要性权重", 0.5)),
            "权重理由": result.get("weight_reason", result.get("权重理由", "")),
            "子节点元素": []
        }

        # 添加图片链接（仅图片元素）
        if element_type == "image" and "image_path" in result:
            element["图片链接"] = result["image_path"]
        elif "图片链接" in result:
            element["图片链接"] = result["图片链接"]

        # 递归处理子节点
        children = result.get("children", result.get("子节点元素", []))
        if children:
            for idx, child in enumerate(children):
                child_element = self._build_element_tree(
                    id=f"{id}_{idx + 1}",
                    result=child,
                    element_type=element_type
                )
                element["子节点元素"].append(child_element)

        return element

    def _validate_result(self, result: Dict[str, Any]) -> None:
        """验证JSON格式（视频分析版本）

        Args:
            result: 最终结果

        Raises:
            ValueError: 格式不正确时抛出异常
        """
        # 检查必需字段（视频分析版本）
        if "视频信息" not in result:
            logger.warning("缺少'视频信息'字段")
            result["视频信息"] = {}

        if "三点解构" not in result:
            logger.warning("缺少'三点解构'字段")
            result["三点解构"] = {
                "灵感点": {},
                "目的点": {},
                "关键点": {}
            }

        if "选题理解" not in result:
            logger.warning("缺少'选题理解'字段")
            result["选题理解"] = {}

        # 验证三点解构结构
        three_points = result["三点解构"]
        if not isinstance(three_points, dict):
            logger.warning("'三点解构'必须是字典")
            result["三点解构"] = {
                "灵感点": {},
                "目的点": {},
                "关键点": {}
            }
        else:
            # 确保三点字段存在
            if "灵感点" not in three_points:
                logger.warning("三点解构缺少'灵感点'字段")
                three_points["灵感点"] = {}
            if "目的点" not in three_points:
                logger.warning("三点解构缺少'目的点'字段")
                three_points["目的点"] = {}
            if "关键点" not in three_points:
                logger.warning("三点解构缺少'关键点'字段")
                three_points["关键点"] = {}

        # 验证选题理解
        if not isinstance(result["选题理解"], dict):
            logger.warning("'选题理解'必须是字典")
            result["选题理解"] = {}

        # 验证搜索关键词
        if "搜索关键词" not in result:
            logger.warning("缺少'搜索关键词'字段")
            result["搜索关键词"] = {
                "搜索词列表": [],
                "总数": 0
            }

        if not isinstance(result["搜索关键词"], dict):
            logger.warning("'搜索关键词'必须是字典")
            result["搜索关键词"] = {
                "搜索词列表": [],
                "总数": 0
            }
        else:
            # 确保搜索关键词结构完整
            if "搜索词列表" not in result["搜索关键词"]:
                logger.warning("搜索关键词缺少'搜索词列表'字段")
                result["搜索关键词"]["搜索词列表"] = []
            if "总数" not in result["搜索关键词"]:
                # 自动计算总数
                search_list = result["搜索关键词"].get("搜索词列表", [])
                result["搜索关键词"]["总数"] = len(search_list)

    def _validate_element(self, element: Dict[str, Any]) -> None:
        """验证元素节点格式（视频分析版本中不再使用，保留以保持代码完整性）

        Args:
            element: 元素节点

        Raises:
            ValueError: 格式不正确时抛出异常
        """
        required_fields = ["id", "what", "描述", "子节点元素关系", "元素重要性权重", "权重理由", "子节点元素"]

        for field in required_fields:
            if field not in element:
                raise ValueError(f"元素节点缺少'{field}'字段")

        # 验证权重范围
        weight = element["元素重要性权重"]
        if not isinstance(weight, (int, float)) or weight < 0 or weight > 1:
            logger.warning(f"元素权重不在[0, 1]范围内: {weight}，已修正")
            element["元素重要性权重"] = max(0, min(1, weight))

        # 递归验证子节点
        for child in element["子节点元素"]:
            self._validate_element(child)
