#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
服务端：经理不再等同管理员，改为「本部门」作用域（2026-09-20，刘欣-销售拓展部经理）
=================================================================================
问题：ai_chat.py / 销售工作台服务.py 多处写 `role in ('admin','gm','manager')` → 经理看到全公司数据
     （特殊要求库 2,865 条、测试报告全部、订单下拉全部），与「只能看本部门」的口径冲突。
做法：经理走 ai_chat._dept_personnel(归一部门) 得到的本部门在职成员集合；admin/gm 才看全部。
"""
import os
import sys

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
AI = os.path.join(ROOT, '脚本', 'ai_chat.py')
SV = os.path.join(ROOT, '脚本', '销售工作台服务.py')

PAT = [
    # ── ai_chat.py ──
    (AI, """    is_full = role in ('admin', 'gm', 'manager')""",
         """    is_full = role in ('admin', 'gm')   # 经理≠管理员：经理只看本部门（走 _visible_customer_names 的部门作用域）"""),
    (AI, """        'can_manage_all': role in ('admin', 'gm', 'manager'),""",
         """        'can_manage_all': role in ('admin', 'gm'),"""),
    # ── 销售工作台服务.py：测试报告选项（订单/客户下拉）──
    (SV, """    if role in ('admin', 'gm', 'manager', 'director') or not name:
        return data
    mine = [o for o in data['orders'] if o.get('sp') == name]
    return {'orders': mine if mine else data['orders'], 'skus': data['skus']}""",
         """    if role in ('admin', 'gm', 'director') or not name:
        return data
    if role == 'manager':
        mem = _dept_members((user or {}).get('dept') or '')
        mine = [o for o in data['orders'] if o.get('sp') in mem] if mem else []
        return {'orders': mine, 'skus': data['skus']}
    mine = [o for o in data['orders'] if o.get('sp') == name]
    return {'orders': mine, 'skus': data['skus']}"""),
    # ── 销售工作台服务.py：测试报告 详情/列表 ──
    (SV, """                if _role not in ('admin', 'gm', 'manager', 'director') and _name and _rec.get('submitted_by') != _name:
                    self._send_json({'ok': False, 'error': '无权查看他人报告'}, 403)
                    return""",
         """                if _test_report_visible_people(_role, _name, _au) is not None and _name \\
                        and _rec.get('submitted_by') not in _test_report_visible_people(_role, _name, _au):
                    self._send_json({'ok': False, 'error': '无权查看他人报告'}, 403)
                    return"""),
    (SV, """            _rows = list_test_reports()
            if _role not in ('admin', 'gm', 'manager', 'director') and _name:
                _mine = [r for r in _rows if r.get('submitted_by') == _name]
                _rows = _mine if _mine else _rows""",
         """            _rows = list_test_reports()
            _vis_p = _test_report_visible_people(_role, _name, _au)
            if _vis_p is not None and _name:
                _rows = [r for r in _rows if r.get('submitted_by') in _vis_p]"""),
    # ── 邮箱兜底映射里的旧部门名 ──
    (SV, """    'liuxin@biori.com': {'name': '刘欣', 'role': 'manager', 'dept': '诊断原料销售拓展部'},""",
         """    'liuxin@biori.com': {'name': '刘欣', 'role': 'manager', 'dept': '销售拓展部'},"""),
]

HELPER = '''

def _dept_members(dept):
    """本部门在职成员姓名集合（部门名做归一：诊断原料销售拓展部 ≡ 销售拓展部）"""
    try:
        sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
        import ai_chat
        return set(ai_chat._dept_personnel(ai_chat._norm_dept(dept)))
    except Exception:
        return set()


def _test_report_visible_people(role, name, user=None):
    """测试报告的可见提交人集合；None = 不限（admin/gm/director）"""
    role = role or ''
    if role in ('admin', 'gm', 'director') or not name:
        return None
    if role == 'manager':
        mem = _dept_members((user or {}).get('dept') or '')
        return mem | {name} if mem else {name}
    return {name}
'''

ANCHOR = "\ndef _load_user_roles():"


def apply(f, pats):
    s = open(f, encoding='utf-8').read()
    n = 0
    for old, new in pats:
        c = s.count(old)
        if c == 1:
            s = s.replace(old, new, 1)
            n += 1
            print('  ✓ %s' % old.strip().splitlines()[0][:70])
        else:
            print('  %s 命中 %d 次: %s' % ('✓已是最新' if new[:50] in s else '✗', c, old.strip().splitlines()[0][:60]))
    return s, n


def main(apply_flag):
    for f, pats in ((AI, PAT[:2]), (SV, PAT[2:])):
        s, n = apply(f, [(o, nw) for _f, o, nw in pats])
        if f == SV and '_dept_members(dept)' not in s:
            assert s.count(ANCHOR) == 1, '找不到插入点'
            s = s.replace(ANCHOR, HELPER + ANCHOR, 1)
            print('  ✓ 插入 _dept_members / _test_report_visible_people')
            n += 1
        if apply_flag and n:
            open(f, 'w', encoding='utf-8').write(s)
            print('  ✅ 已写入 %s（%d 处）' % (os.path.basename(f), n))
        elif not apply_flag:
            print('  （预览：%s 待改 %d 处）' % (os.path.basename(f), n))


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