"""验证年度预算分解幂等 — R5 (2026-08-30)

调用 /api/cma/budget/auto-decompose 3 次，对比月度预算值是否不变。
用法: cd /root/cma-management/backend && ./venv/bin/python3 scripts/verify_decompose_idempotent.py
"""
import sys
import os
import json
import urllib.request

BASE = os.getenv("CMA_BASE", "http://127.0.0.1:8010")


def post(path, body, token=None):
    req = urllib.request.Request(
        BASE + path,
        data=json.dumps(body).encode("utf-8"),
        headers={"Content-Type": "application/json",
                 "Authorization": f"Bearer {token}" if token else ""},
    )
    with urllib.request.urlopen(req, timeout=30) as resp:
        return json.loads(resp.read().decode("utf-8"))


def main():
    # 登录（账套模式必须 entity_id）
    login = post("/api/cma/auth/login", {"username": "admin", "password": "admin123", "entity_id": 1})
    token = login.get("token") or login.get("access_token")
    if not token:
        print("❌ 登录失败:", login)
        sys.exit(1)
    print("✅ 登录成功")

    runs = []
    for i in range(3):
        r = post("/api/cma/budget/auto-decompose", {"year": 2026, "method": "equal", "version": "v1.0"}, token)
        print(f"第{i+1}次: {r.get('message', '')} created={r.get('created', 0)}")
        # 提取 (kpi_id -> monthly tuple)
        snap = {}
        for res in r.get("results", []):
            snap[res["kpi_id"]] = tuple(res.get("monthly") or [])
        runs.append(snap)

    # 对比三次结果
    same = runs[0] == runs[1] == runs[2]
    print(f"\n三次结果一致: {'✅ 是（幂等）' if same else '❌ 否（不幂等）'}")
    if not same:
        for i in range(1, 3):
            for kid in runs[0]:
                if runs[0].get(kid) != runs[i].get(kid):
                    print(f"  KPI {kid} 第1次={runs[0].get(kid)} 第{i+1}次={runs[i].get(kid)}")
    sys.exit(0 if same else 1)


if __name__ == "__main__":
    main()
