#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""拜访与活动：后端加「部门 → 销售 → 客户」三级下钻管道。

- 部门口径：数据/user_roles.json 的 dept；生命科学-浙江/广东 归一到「生命科学销售部」下的一级区域
- 归属人：优先 submitted_by（谁记的），空则用 sales；都不在用户表 → 「未匹配部门」
- 响应新增 groups: [{dept, offline, online, other, total, sales_count, sales:[{name, region, customers:[...]}]}]
  同时保留原有扁平 customers（供「按客户」维度）
"""
import io
import os
import shutil
import sys
import time

ROOT = '/Users/liuxinyuan/Desktop/Hermes输出-工作类'
F = os.path.join(ROOT, '脚本', '销售工作台服务.py')

HELPER_ANCHOR = 'TD_SCOPE = {'
HELPER = '''DEPT_SPLIT = {'生命科学-浙江': ('生命科学销售部', '浙江'),
              '生命科学-广东': ('生命科学销售部', '广东')}


def _sales_dept_map():
    """姓名 → (部门, 区域)。部门两级归一：生命科学-浙江/广东 → 生命科学销售部 + 区域。

    数据源：数据/user_roles.json（服务端快照）。不在表里的（离职/代管/订单销售员）归「未匹配部门」。
    """
    m = {}
    try:
        for u in _load_user_roles():
            nm = (u.get('name') or '').strip()
            if not nm:
                continue
            raw = (u.get('dept') or '').strip()
            dept, region = DEPT_SPLIT.get(raw, (raw or '未匹配部门', ''))
            m[nm] = (dept, region)
    except Exception:
        pass
    return m


'''

GROUP_ANCHOR = '            # 近 12 个月趋势（同一权限与 scope 口径）'
GROUP = '''            # ── 部门 → 销售 → 客户 三级下钻管道 ──
            _dmap = _sales_dept_map()
            _g = {}
            for x in monthly:
                _ch = (x.get('channel') or '').strip()
                _k = _ch if _ch in ('offline', 'online') else 'other'
                _own = (x.get('submitted_by') or '').strip() or (x.get('sales') or '').strip() or '(未知)'
                _dept, _reg = _dmap.get(_own, ('未匹配部门', ''))
                gd = _g.setdefault(_dept, {'dept': _dept, 'offline': 0, 'online': 0, 'other': 0, 'sales': {}})
                gd[_k] += 1
                gs = gd['sales'].setdefault(_own, {'name': _own, 'dept': _dept, 'region': _reg,
                                                   'offline': 0, 'online': 0, 'other': 0, 'customers': {}})
                gs[_k] += 1
                _c = (x.get('customer') or '').strip() or '(未填客户)'
                gc = gs['customers'].setdefault(_c, {'customer': _c, 'offline': 0, 'online': 0, 'other': 0, 'acts': []})
                gc[_k] += 1
                gc['acts'].append({'id': x.get('id', ''), 'date': x.get('date', ''), 'channel': _ch,
                                   'type': x.get('type', ''), 'sales': x.get('sales', '')})
            groups = []
            for gd in _g.values():
                gd['total'] = gd['offline'] + gd['online'] + gd['other']
                _sl = []
                for gs in gd['sales'].values():
                    gs['total'] = gs['offline'] + gs['online'] + gs['other']
                    _cl = list(gs['customers'].values())
                    for gc in _cl:
                        gc['total'] = gc['offline'] + gc['online'] + gc['other']
                        gc['acts'].sort(key=lambda a: a.get('date') or '', reverse=True)
                    _cl.sort(key=lambda d: -d['total'])
                    gs['customers'] = _cl
                    gs['customer_count'] = len(_cl)
                    _sl.append(gs)
                _sl.sort(key=lambda d: -d['total'])
                gd['sales'] = _sl
                gd['sales_count'] = len(_sl)
                groups.append(gd)
            groups.sort(key=lambda d: -d['total'])

'''

RESP_OLD = "                             'customers': sorted(cust.values(), key=lambda d: -d['total'])})"
RESP_NEW = ("                             'departments': groups, 'dept_count': len(groups),\n"
            "                             'customers': sorted(cust.values(), key=lambda d: -d['total'])})")


def main():
    apply = '--apply' in sys.argv
    s = io.open(F, encoding='utf-8').read()
    print('拜访与活动·三级下钻后端补丁 —— %s\n' % ('APPLY' if apply else 'DRY-RUN'))
    ok = True
    for label, old, new in [('A 部门映射辅助', HELPER_ANCHOR, HELPER + HELPER_ANCHOR),
                            ('B 三级聚合', GROUP_ANCHOR, GROUP + GROUP_ANCHOR),
                            ('C 响应加 departments', RESP_OLD, RESP_NEW)]:
        n = s.count(old)
        print('  %s %-20s 命中 %d' % ('✅' if n == 1 else '❌', label, n))
        if n != 1:
            ok = False
        else:
            s = s.replace(old, new, 1)
    if not ok:
        print('\n有未命中 → 不落盘')
        return 1
    if apply:
        ts = time.strftime('%Y%m%d-%H%M%S')
        bak = os.path.join(ROOT, '_bak_p2b_dept_%s' % ts)
        os.makedirs(bak, exist_ok=True)
        shutil.copy2(F, os.path.join(bak, os.path.basename(F)))
        io.open(F, 'w', encoding='utf-8').write(s)
        print('\n  已写（备份 %s）' % bak)
    else:
        print('\n  干跑通过，未落盘。')
    return 0


sys.exit(main())
