"""查询树节点自身、父节点、兄弟节点的局部热度与排名。"""
from __future__ import annotations

import logging
from typing import Any

from agents.demand_grade_agent.tools.shared import normalize_biz_dt
from agents.demand_grade_agent.tools.tree_local import render_local_heat_report
from supply_agent.tools import tool

logger = logging.getLogger(__name__)


def _normalize_ids(category_ids: list[Any]) -> tuple[list[int], str | None]:
    if not category_ids:
        return [], "category_ids 不能为空"
    out: list[int] = []
    seen: set[int] = set()
    for raw in category_ids:
        try:
            cid = int(raw)
        except (TypeError, ValueError):
            return [], f"category_ids 含无效 id: {raw!r}"
        if cid in seen:
            continue
        seen.add(cid)
        out.append(cid)
    if not out:
        return [], "category_ids 不能为空"
    return out, None


@tool
def query_category_local_heat(biz_dt: str, category_ids: list[int]) -> str:
    """查询节点自身、父节点、全部兄弟节点的全局热度与后验数据及兄弟内排名。

    只返回 total_score 与后验 rov_diff/vov_diff（real_rov_7d/real_vov_7d），不包含四维先验明细。
    """
    normalized_dt, err = normalize_biz_dt(biz_dt)
    if err:
        return err
    ids, err = _normalize_ids(category_ids)
    if err:
        return err

    try:
        report = render_local_heat_report(normalized_dt, ids)
        logger.info("query_category_local_heat completed: biz_dt=%s ids=%s", normalized_dt, ids)
        return report
    except Exception as exc:
        logger.error("query_category_local_heat failed: %s", exc, exc_info=True)
        return f"查询局部树节点热度失败: {exc}"


if __name__ == "__main__":
    print(query_category_local_heat("20260714", [313, 686]))
