"""Dump 5 棵作用域分类树（PG public.global_category）→ 本地 JSON。

产物（scope_trees/）：
  - trees.json        整个分类树，按 source_type 分组（含已退役节点，live 标记）
  - trees_index.json  仅 live 节点（scope-link 定位目标），与 trees_embeddings.npy 行对齐

须在能连 RDS 的环境跑（云端）。用法：python scripts/dump_trees.py [env_file]
"""
from __future__ import annotations

import json
import sys
from collections import Counter
from pathlib import Path

from core.config import PgConfig
from core.db import fetch_all

OUT = Path("scope_trees")


def fetch_nodes(cfg: PgConfig) -> list[dict]:
    return fetch_all(
        cfg,
        "SELECT stable_id, name, source_type, path, level, parent_stable_id, "
        "(retired_at_execution_id IS NULL) AS live "
        "FROM global_category ORDER BY source_type, level, stable_id",
        schema="public",
    )


def main(env_file: str = ".env") -> None:
    cfg = PgConfig.from_env(env_file)
    rows = fetch_nodes(cfg)
    OUT.mkdir(exist_ok=True)

    trees: dict[str, list[dict]] = {}
    for r in rows:
        trees.setdefault(r["source_type"], []).append({
            "stable_id": r["stable_id"], "name": r["name"], "path": r["path"],
            "level": r["level"], "parent_stable_id": r["parent_stable_id"],
            "live": r["live"],
        })
    (OUT / "trees.json").write_text(
        json.dumps(trees, ensure_ascii=False, indent=2), encoding="utf-8")

    live_rows = [r for r in rows if r["live"]]
    index = [{
        "row": i, "stable_id": r["stable_id"], "source_type": r["source_type"],
        "name": r["name"], "path": r["path"],
    } for i, r in enumerate(live_rows)]
    (OUT / "trees_index.json").write_text(
        json.dumps(index, ensure_ascii=False, indent=2), encoding="utf-8")

    total = Counter(r["source_type"] for r in rows)
    live = Counter(r["source_type"] for r in live_rows)
    print("trees.json  (全部):", dict(total), "总计", sum(total.values()))
    print("trees_index (live):", dict(live), "总计", len(index))


if __name__ == "__main__":
    main(sys.argv[1] if len(sys.argv) > 1 else ".env")
