#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
修「销售员」列：把客户名换成真正的归属销售员
============================================
bug 根因同上一个（单据号）：extract_erp_remarks.py 生成条目时 owner 取了该批第 1 条的
客户名，于是页面上「销售员」一列显示的是客户名称。
正确来源：ERP 主表「客户+销售员」建出的客户归属映射（数据/pricing/_key_customers.json），
高校/科研客户回退到课题组归属（数据/ls_groups.json）。取不到就留空，绝不填错的名字。

用法：python3 fix_owner.py [--apply]
"""
import os
import re
import sys
import json

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LIB = os.path.join(ROOT, '数据', 'customer_special_requirements.json')
REVIEW = os.path.join(ROOT, '数据', 'sr_review.json')
KC = os.path.join(ROOT, '数据', 'pricing', '_key_customers.json')
LSG = os.path.join(ROOT, '数据', 'ls_groups.json')

# 非人名/无意义的值（这些都不是销售员）
BAD = {'', '无', '待定', '待确认', '未知', '全部', '共1个', '共2个', '共3个', '共4个', '共5个'}


def _s(v):
    if v is None:
        return ''
    t = str(v).strip()
    return '' if t.lower() in ('nan', 'none', 'null', 'nat') else t


def norm(s):
    return re.sub(r'[\s，。；;、：:（）()【】\[\]！!？?\-—_/]+', '', _s(s))


def load_map():
    """(客户名 → 销售员) 覆盖映射 + 关键词索引"""
    mp = {}
    kc = json.load(open(KC, encoding='utf-8'))
    rows = kc if isinstance(kc, list) else (kc.get('customers') or [])
    for c in rows:
        if not isinstance(c, dict):
            continue
        name = _s(c.get('name'))
        sp = _s(c.get('salesperson') or c.get('sales'))
        if name and sp and sp not in BAD:
            mp[name] = sp
    # 课题组（高校/科研）归属
    if os.path.exists(LSG):
        try:
            g = json.load(open(LSG, encoding='utf-8'))
            grows = g if isinstance(g, list) else (g.get('groups') or [])
            for c in grows:
                if not isinstance(c, dict):
                    continue
                name, sp = _s(c.get('name')), _s(c.get('sales') or c.get('salesperson') or c.get('owner'))
                if name and sp and sp not in BAD:
                    mp.setdefault(name, sp)
        except Exception:
            pass
    return mp


def lookup(mp, customer, norm_map):
    """客户名 → 销售员：先精确，再互相包含（ERP 全称 vs 库里简称）"""
    cust = _s(customer)
    if cust in mp:
        return mp[cust]
    n = norm(cust)
    if not n:
        return ''
    for k, sp in norm_map.items():
        if k and (k in n or n in k):
            return sp
    return ''


def main(apply):
    mp = load_map()
    norm_map = {norm(k): v for k, v in mp.items()}
    print('  归属映射 %d 个客户（来源：ERP 客户+销售员 / 课题组）' % len(mp))
    hit = miss = 0
    bad_before = 0
    for path, is_lib in ((LIB, True), (REVIEW, False)):
        d = json.load(open(path, encoding='utf-8'))
        rows = d.get('items') if is_lib else d.get('rows')
        for it in rows:
            cust = it.get('customer') or ''
            if _s(it.get('owner') or it.get('salesperson') or it.get('activity_owner')) == _s(cust):
                bad_before += 1
            sp = lookup(mp, cust, norm_map)
            if is_lib:
                it['owner'] = sp                     # 取不到就是空，不留客户名
            else:
                it['salesperson'] = sp
                it['activity_owner'] = sp
            if sp:
                hit += 1
            else:
                miss += 1
        if is_lib:
            d['version'] = int(d.get('version') or 1) + 1
        if apply:
            json.dump(d, open(path, 'w', encoding='utf-8'), ensure_ascii=False, indent=1)
    print('  ✅ 填上销售员 %d 条 ｜ 取不到留空 %d 条 ｜ 原先是客户名的 %d 条' % (hit, miss, bad_before))
    if not apply:
        print('  （预览模式，未写入；加 --apply 生效）')


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