#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
合并 user_roles.json 的重复人员条目（46 条 → 25 人各一条）
==========================================================
背景：该文件是「历史种子 + CloudBase 同步快照」叠加而成，同一个人常有两条：
  A 条：旧部门名（诊断原料销售拓展部 / 生命科学-浙江）+ 完整 tabs（8~14 项）
  B 条：新部门名（销售拓展部 / 大客户部 / 生命科学销售部）+ 稀疏 tabs（{"dashboard":true}）
后果：权限面板下拉里同一人出现两次、且部门标签两套；若某人只存在 A 条
（如刘欣：销售拓展部经理），按新部门名就找不到他。

合并规则（保守）：
- dept：优先新命名；旧名做映射归一（诊断原料销售拓展部→销售拓展部，
  诊断原料大客户销售部→大客户部，生命科学-浙江/广东→生命科学销售部）
- tabs：取项目更多的那份（更明确）；role：取权限更高的一份
- pwd / email / open_id / line / status：取非空；_id 取主条目，其余记入 _merged_ids
用法：python3 merge_user_roles.py [--apply]
"""
import os
import sys
import json
import shutil

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
F = os.path.join(ROOT, '数据', 'user_roles.json')

DEPT_NORM = {
    '诊断原料销售拓展部': '销售拓展部',
    '诊断原料大客户销售部': '大客户部',
    '生命科学-浙江': '生命科学销售部',
    '生命科学-广东': '生命科学销售部',
    '诊断原料销售部': '诊断原料销售部',
}
ROLE_RANK = {'sales': 1, 'manager': 2, 'gm': 3, 'admin': 4}


def main(apply):
    u = json.load(open(F, encoding='utf-8'))
    order, groups = [], {}
    for x in u:
        nm = x.get('name') or ''
        if nm not in groups:
            groups[nm] = []
            order.append(nm)
        groups[nm].append(x)

    out = []
    for nm in order:
        items = groups[nm]
        items_sorted = sorted(items, key=lambda x: (-ROLE_RANK.get(x.get('role') or 'sales', 0),
                                                   -len(x.get('tabs') or {})))
        base = dict(items_sorted[0])
        # dept：优先「信息量最大」的写法——含区域(浙江/广东)的最优先（服务端靠它分区域），
        # 其次新命名（销售拓展部/大客户部/生命科学销售部），最后旧命名
        def _rank(d):
            d = d or ''
            if '浙江' in d or '广东' in d:
                return 0
            if d not in DEPT_NORM:
                return 1
            return 2
        cand = sorted({(x.get('dept') or '') for x in items}, key=_rank)
        dd = (cand or [''])[0]
        # 只剩旧名时才归一（保留 生命科学-浙江/广东 这类带区域信息的写法）
        dd = {'诊断原料销售拓展部': '销售拓展部', '诊断原料大客户销售部': '大客户部'}.get(dd, dd)
        base['dept'] = dd
        # role / tabs：取更强者
        base['role'] = max((x.get('role') or 'sales' for x in items), key=lambda r: ROLE_RANK.get(r, 0))
        tabs = {}
        for x in sorted(items, key=lambda y: -len(y.get('tabs') or {})):
            for k, v in (x.get('tabs') or {}).items():
                tabs.setdefault(k, v)
        base['tabs'] = tabs
        # 非空字段补齐
        for k in ('email', 'open_id', 'line', 'status', 'pwd', 'password'):
            if not base.get(k):
                base[k] = next((x.get(k) for x in items if x.get(k)), base.get(k))
        ids = [x.get('_id') for x in items if x.get('_id')]
        if len(ids) > 1:
            base['_merged_ids'] = ids[1:]
        out.append(base)

    print('  合并前 %d 条 → 合并后 %d 人' % (len(u), len(out)))
    dup = [(nm, len(groups[nm])) for nm in order if len(groups[nm]) > 1]
    print('  合并掉的重复: %d 人 %s' % (len(dup), '、'.join('%s×%d' % d for d in dup[:8]) + ('…' if len(dup) > 8 else '')))
    lx = next((x for x in out if x['name'] == '刘欣'), None)
    if lx:
        print('  刘欣 → role=%s dept=%s line=%s tabs=%d 项 email=%s' % (lx.get('role'), lx.get('dept'), lx.get('line'), len(lx.get('tabs') or {}), lx.get('email')))
    lose = [nm for nm in order if any(any(k in x for k in ('pwd', 'password')) for x in groups[nm])
            and not any(k in out[order.index(nm)] for k in ('pwd', 'password'))]
    print('  密码字段丢失的人: %s' % ('无 ✓' if not lose else '、'.join(lose) + ' ✗'))
    if apply:
        shutil.copy(F, F + '.bak_before_merge')
        json.dump(out, open(F, 'w', encoding='utf-8'), ensure_ascii=False, indent=1)
        print('  ✅ 已写入（备份 .bak_before_merge）')
    else:
        print('  （预览模式；加 --apply 生效）')


if __name__ == '__main__':
    main('--apply' in sys.argv[1:])
