#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""验证：销售员归并（四 人 → 刘子研）+ 目标 1300 万，其他人零变化。

对比 BEFORE（改前备份）与 AFTER（当前产物）。
"""
import json, sys
from collections import defaultdict

BEFORE = "/Users/liuxinyuan/Desktop/Hermes输出-工作类/脚本/_bak_spmerge_20261006_132457/三部门逐月_2026.json.BEFORE"
AFTER = "/Users/liuxinyuan/Desktop/Hermes输出-工作类/数据/三部门逐月_2026.json"
FOUR = ("刘子研", "黄明月", "张立娅", "刘新元")

B = json.load(open(BEFORE, encoding="utf-8"))
A = json.load(open(AFTER, encoding="utf-8"))

print("=" * 70)
print("【1】刘子研 合并后两口径")
spA = A["salespersons"]
tot_sp = sum(r["amt"] for r in spA if r.get("sp") == "刘子研")
rows_sp = [r for r in spA if r.get("sp") == "刘子研"]
cuA = A["customers"]
cu_liu = [c for c in cuA if c.get("sales") == "刘子研"]
tot_cu = sum(c["amt"] for c in cu_liu)
n_cust = len({c["cust"] for c in cu_liu})
print(f"  salespersons 刘子研 合计 = {tot_sp:,.2f} 万（{len(rows_sp)} 月行）")
print(f"  customers  sales==刘子研 = {tot_cu:,.2f} 万（{n_cust} 个客户）")
print(f"  两口径差 = {abs(tot_sp - tot_cu):,.2f} 万 ({abs(tot_sp-tot_cu)/tot_cu*100:.2f}%)")
# 改前
tot_sp_b = sum(r["amt"] for r in B["salespersons"] if r.get("sp") == "刘子研")
tot_cu_b = sum(c["amt"] for c in B["customers"] if c.get("sales") == "刘子研")
print(f"  [改前] salespersons 刘子研 = {tot_sp_b:,.2f} ｜ customers sales==刘子研 = {tot_cu_b:,.2f}"
      f"（差 {abs(tot_sp_b-tot_cu_b):,.2f} 万 = {abs(tot_sp_b-tot_cu_b)/tot_sp_b*100:.0f}%）")

print("=" * 70)
print("【2】其他人零变化断言")
# --- salespersons 逐值 diff（除四人）---
bc = {(r["month"], r["dept"], r["sp"]): dict(r) for r in B["salespersons"]}
ac = {(r["month"], r["dept"], r["sp"]): dict(r) for r in A["salespersons"]}
keys = set(bc) | set(ac)
sp_files = ["target", "achieve", "target_annual", "achieve_ytd"]
diff_sp = []
for k in sorted(keys):
    if k[2] in FOUR:
        continue
    rb, ra = bc.get(k), ac.get(k)
    if rb is None or ra is None:
        diff_sp.append((k, "ROW_MISSING", rb is None, ra is None)); continue
    for f in ("amt", "custs") + tuple(sp_files):
        if rb.get(f) != ra.get(f):
            diff_sp.append((k, f, rb.get(f), ra.get(f)))
print(f"  salespersons 非四人键数={len([k for k in keys if k[2] not in FOUR])}  逐值差异={len(diff_sp)}")
for d in diff_sp[:20]:
    print("    ❌", d)
print(f"  结论: {'✅ 32 人逐值完全相同' if not diff_sp else '❌ 有差异'}")

# --- customers 归属 diff（除四人）---
def own_sig(d):
    return {(c["month"], c["dept"], c["cust"]): (c.get("sales"), c.get("amt"), c.get("amt_2025"), c.get("grp"))
            for c in d["customers"]}
sb, sa = own_sig(B), own_sig(A)
ks = set(sb) | set(sa)
diff_c = 0
diff_c_four = 0
for k in ks:
    vb, va = sb.get(k), sa.get(k)
    if vb == va:
        continue
    # 只允许「四人」相关归属变化
    b_own, a_own = (vb or (None,))[0], (va or (None,))[0]
    if b_own in FOUR or a_own in FOUR:
        diff_c_four += 1
        continue
    diff_c += 1
    if diff_c <= 10:
        print("    ❌", k, vb, "->", va)
print(f"  customers 行键：{len(sb)} -> {len(sa)}")
print(f"  归属变化行数（涉及四人）= {diff_c_four}  ← 预期变化")
print(f"  归属变化行数（与四人无关）= {diff_c}  ← 必须为 0")
print(f"  结论: {'✅ 其他人归属零变化' if diff_c == 0 else '❌ 有无关变化'}")

print("=" * 70)
print("【3】金额守恒")
for nm, key in (("Σamt", "amt"), ("Σamt_2025", "amt_2025")):
    eA = round(sum(c.get(key) or 0 for c in A["customers"]), 2)
    gA = round(sum(c.get(key) or 0 for c in A["customers_grp"]), 2)
    eB = round(sum(c.get(key) or 0 for c in B["customers"]), 2)
    gB = round(sum(c.get(key) or 0 for c in B["customers_grp"]), 2)
    print(f"  {nm}: customers={eA:,.2f}  customers_grp={gA:,.2f}  相等={abs(eA-gA)<0.05}  改前={eB:,.2f}/{gB:,.2f}  与改前相同={abs(eA-eB)<0.05}")
# 实体口径（部门/总计）不变
print(f"  depts 实际合计 改前/改后 = {round(sum(sum(A['depts'][d]['actual_monthly'].values()) for d in A['depts']),2)} / "
      f"{round(sum(sum(B['depts'][d]['actual_monthly'].values()) for d in B['depts']),2)}")
print(f"  total.target_annual = {A['total']['target_annual']}  月目标合计 = {round(sum(A['total']['target_monthly'].values()),2)}")

print("=" * 70)
print("【4】合并后不再出现 黄明月/张立娅")
names_sp = sorted({r.get("sp") for r in A["salespersons"]})
bad_sp = [n for n in ("黄明月", "张立娅", "刘新元") if n in names_sp]
sales_bad = sorted({c.get("sales") for c in A["customers"] if c.get("sales") in ("黄明月", "张立娅", "刘新元")})
print(f"  salespersons 是否含 黄明月/张立娅/刘新元: {bad_sp or '无 ✅'}")
print(f"  customers sales 是否含 这三人: {sales_bad or '无 ✅'}")
print(f"  salespersons 唯一人数 = {len(names_sp)}（改前 {len({r['sp'] for r in B['salespersons']})}）")

print("=" * 70)
print("【5】target_annual / 无 0 值")
for nm in ("刘子研",):
    vals = sorted({r.get("target_annual") for r in A["salespersons"] if r.get("sp") == nm})
    print(f"  {nm}.target_annual = {vals}")
# 其他人 target_annual 零变化
ta_b = {(r["month"], r["dept"], r["sp"]): r.get("target_annual") for r in B["salespersons"]}
ta_a = {(r["month"], r["dept"], r["sp"]): r.get("target_annual") for r in A["salespersons"]}
bad_ta = [(k, ta_b.get(k), ta_a.get(k)) for k in (set(ta_b) | set(ta_a))
          if k[2] not in FOUR and ta_b.get(k) != ta_a.get(k)]
print(f"  其他人 target_annual 差异 = {len(bad_ta)}  {bad_ta[:5]}")
# 无 0 值：任何 target 不得为 0
zeros = [r for r in A["salespersons"] if r.get("target") == 0]
print(f"  target==0 的行数 = {len(zeros)}  {'✅ 无 0' if not zeros else '❌'}")
zl = [r for r in A["salespersons"] if r.get("sp") == "刘子研" and r["month"] < "2026-07"]
print(f"  刘子研 1-6 月 target 值 = {sorted({r.get('target') for r in zl})}（应全为 None）")

print("=" * 70)
print("【6】customers_grp mixed / partial 影响面")
mb = len([g for g in B["customers_grp"] if g.get("mixed")])
ma = len([g for g in A["customers_grp"] if g.get("mixed")])
print(f"  customers_grp mixed 行数: 改前 {mb} -> 改后 {ma}")
m31b = len([g for g in B["customers_grp"] if "刘新元" in (g.get("sales_list") or [])])
m31a = len([g for g in A["customers_grp"] if "刘新元" in (g.get("sales_list") or [])])
print(f"  sales_list 含 刘新元 的行数: 改前 {m31b} -> 改后 {m31a}")
zd = [g for g in A["customers_grp"] if "珠海丽珠试剂股份有限公司" in str(g.get("cust")) or "天隆集团" in str(g.get("cust"))]
print(f"  meta.person_merge present = {'person_merge' in (A.get('meta') or {})}")
print(json.dumps((A.get("meta") or {}).get("person_merge"), ensure_ascii=False, indent=1)[:900])
