"""下钻节点，查看整树位置及父子/兄弟间的全局热度（未分批节点标 +）。"""
from __future__ import annotations

from agents.demand_grade_orchestrator_agent.common.assignment import get_unassigned_hanging_category_ids
from agents.demand_grade_orchestrator_agent.common import (
    format_heat_score,
    format_rank,
    global_heat_positions,
    has_hung_demand,
    heat_level,
    load_tree_state,
    path,
)
from supply_infra.scoring.posterior import format_posterior_pair
from supply_agent.tools import tool


@tool
def query_heat_node_group(biz_dt: str, category_ids: list[int]) -> str:
    """返回指定节点、父节点、全部兄弟和直接子节点的整树名次及热度等级。"""
    by_id, children, weights = load_tree_state(biz_dt)
    positions = global_heat_positions(weights)
    unassigned_nodes = get_unassigned_hanging_category_ids(biz_dt)
    lines = [
        f"biz_dt={biz_dt} | 格式：[分类ID]分类名称[total_score|整树名次|热度等级] + [| rov_diff/vov_diff] | "
        "名次在整棵有分节点中计算；无数据为 null/U；+ 仅表示未分批且有挂载需求；"
        "后验为相对全局 diff：>0 优、[-0.2,0) 可接受、<-0.2 不佳"
    ]

    def describe(category_id: int) -> str:
        category = by_id[category_id]
        weight = weights.get(category_id)
        position = positions.get(category_id)
        is_unassigned = category_id in unassigned_nodes
        suffix = " +" if is_unassigned and has_hung_demand(weight) else ""
        posterior = ""
        if weight is not None and int(getattr(weight, "real_rov_7d_count", 0) or 0) > 0:
            posterior = (
                f" | {format_posterior_pair(weight.real_rov_7d_avg, weight.real_rov_7d_count, weight.real_vov_7d_avg, weight.real_vov_7d_count)}"
            )
        return (
            f"[{category_id}]{category.name or ''}"
            f"[{format_heat_score(weight)}|{format_rank(position)}|{heat_level(position)}]{suffix}{posterior}"
        )

    for category_id in dict.fromkeys(int(value) for value in category_ids):
        category = by_id.get(category_id)
        if category is None:
            continue
        parent_id = int(category.parent_id) if category.parent_id not in (None, 0) else None
        lines.append(f"节点：{describe(category_id)}")
        lines.append(f"  路径：{path(category_id, by_id)}")
        if parent_id is not None:
            lines.append(f"  父节点：{describe(parent_id)}")
        sibling_text = "、".join(describe(sibling) for sibling in children.get(parent_id, []))
        lines.append(f"  全部兄弟节点（含自身）：{sibling_text or '无'}")
        child_text = "、".join(describe(child) for child in children.get(category_id, []))
        lines.append(f"  直接子节点：{child_text or '无'}")
    return "\n".join(lines)
