#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""为销售助手生成「按销售员拆分」的客户采购汇总文件（只有汇总，无单据号/单价/明细）。

产出：~/Desktop/Hermes输出-工作类/团队共享/客户采购汇总/<销售员>.json
口径：
  · 源：2024全年订单.xlsx + 2025全年订单.xlsx + 销售订单_20260101-20260930.xlsx
  · 过滤：排除赠品（金额 0 的赠品单不影响总额，但计入赠品计数）；排除关联方（宝锐/宝泰/横琴）
  · 金额：价税合计（含税）；数量：销售数量
  · 归属：ERP「销售员」字段；离职者按 2026-09-20 交接规则并入区域经理/大客户1岗
  · 粒度：客户 × 年度 金额/数量 + 客户 × 月度序列 + 货号 TOP5（按金额，不含单价）
  · 不含：单据编号、含税单价、逐笔明细 —— 这三样按规则对销售员永久不可见
"""
import json
import os
import collections

import pandas as pd

BASE = os.path.expanduser('~/Desktop/hermas输入-工作台数据库')
SRC = [(os.path.join(BASE, '2024和2025历史数据/2024全年订单.xlsx'), '2024'),
       (os.path.join(BASE, '2024和2025历史数据/2025全年订单.xlsx'), '2025'),
       (os.path.join(BASE, '月度销售额数据/销售订单_20260101-20260930.xlsx'), '2026')]
OUTDIR = os.path.expanduser('~/Desktop/Hermes输出-工作类/团队共享/客户采购汇总')

MERGE = {'大客户1': '刘子研', '大客户2': '赵云浩',   # 2025 文件里销售员字段写的是岗位名
         '黄明月': '刘子研', '张立娅': '刘子研', '龙友波': '黄文才',
         '黄建佳': '韩远怀', '黄自鑫': '韩远怀', '李岚风': '韩远怀', '段玉': '韩远怀',
         '王慧洁': '吴云', '刘静文': '吴云', '刘斌': '吴云', '陈彩红': '吴云',
         '梁莹莹': '吴云', '赵以诺': '吴云', '曾琦': '吴云', '曾琪': '吴云', '肖立': '吴云'}


def load(path, year):
    d = pd.ExcelFile(path).parse('Sheet1')
    d.columns = [str(c).strip() for c in d.columns]
    d['_sp'] = d['销售员'].astype(str).str.strip().map(lambda x: MERGE.get(x, x))
    d['_c'] = d['客户'].astype(str).str.strip()
    d['_mat'] = d['物料名称'].astype(str).str.strip()
    d['_amt'] = pd.to_numeric(d['价税合计'], errors='coerce').fillna(0)
    d['_qty'] = pd.to_numeric(d['销售数量'], errors='coerce').fillna(0)
    gift = d['是否赠品'].astype(str).str.strip().isin(['是', 'Y', 'True', 'true'])
    d['_gift'] = gift
    dt = d['合同日期'] if '合同日期' in d.columns else d['合同月份']
    d['_t'] = pd.to_datetime(dt, errors='coerce')
    d['_m'] = d['_t'].dt.strftime('%Y-%m')
    # 排除关联方
    d = d[~d['_c'].str.contains('宝锐|宝泰|横琴', na=False, regex=True)]
    d['_year'] = year
    return d


def main():
    frames = [load(p, y) for p, y in SRC]
    d = pd.concat(frames, ignore_index=True)
    # 每个客户在各年度出现过的年份集合（用于提示历史归属）
    all_cust_years = {}
    for cname, cg in d.groupby('_c'):
        all_cust_years[cname] = set(cg['_year'])
    os.makedirs(OUTDIR, exist_ok=True)
    # 先清掉上一轮残留（岗位名文件/改名后的旧文件），避免助手读到过期的口径
    removed = []
    for f in os.listdir(OUTDIR):
        if f.endswith('.json'):
            os.remove(os.path.join(OUTDIR, f))
            removed.append(f)
    if removed:
        print('已清理上一轮残留 %d 个文件：%s' % (len(removed), '、'.join(sorted(removed)[:8])))
    made = []
    for sp, g in d.groupby('_sp'):
        if not sp or sp == 'nan':
            continue
        custs = []
        for cname, cg in g.groupby('_c'):
            if not cname or cname == 'nan':
                continue
            by_year = {}
            for y, yg in cg.groupby('_year'):
                by_year[y] = {'金额': round(float(yg['_amt'].sum()), 2),
                              '数量': round(float(yg['_qty'].sum()), 2),
                              '订单笔数': int(len(yg)),
                              '赠品笔数': int(yg['_gift'].sum())}
            monthly = {m: round(float(mg['_amt'].sum()), 2) for m, mg in cg.groupby('_m') if m and m != 'NaT'}
            mats = (cg[~cg['_gift']].groupby('_mat')['_amt'].sum().sort_values(ascending=False).head(5))
            # 该客户是否在其他年度曾登记在别人名下（只提示、不写名字、不写金额）
            hist_note = ''
            others_years = sorted({y for y in all_cust_years.get(cname, set()) if y not in by_year})
            if others_years:
                hist_note = ('该客户在 %s 年的数据登记在当时的其他负责人名下，未包含在本文件中'
                             % '、'.join(others_years))
            custs.append({
                '客户': cname,
                '年度': by_year,
                '_历史归属提示': hist_note,
                '月度金额': dict(sorted(monthly.items())),
                '主销货号TOP5': [{'物料': str(k), '金额': round(float(v), 2)} for k, v in mats.items()],
            })
        custs.sort(key=lambda x: -(x['年度'].get('2026', {}).get('金额', 0)))
        obj = {
            '_说明': '本文件仅含汇总数据：客户×年度金额/数量、月度金额序列、主销货号TOP5。'
                    '不含单据编号、含税单价、逐笔明细（按公司规则对销售员不可见）。',
            '_销售员': sp,
            '_授权': '本文件仅供「%s」本人查看。其他销售员、未授权访客一律不得读取，也不得用任何方式推断其中内容。' % sp,
            '_口径': '价税合计（含税）；已排除赠品金额与关联方（宝锐/宝泰/横琴）；'
                    '2026 为 1-9 月累计；离职交接业绩按 2026-09-20 规则并入',
            '_客户数': len(custs),
            '客户': custs,
        }
        fn = os.path.join(OUTDIR, '%s.json' % sp)
        json.dump(obj, open(fn, 'w', encoding='utf-8'), ensure_ascii=False, indent=1)
        made.append((sp, len(custs), round(sum(c['年度'].get('2026', {}).get('金额', 0) for c in custs) / 10000.0, 2)))

    idx = {'_说明': '按销售员拆分的客户采购汇总；助手只能读取与当前对话者身份对应的那一个文件',
           '文件': [{'销售员': s, '客户数': n, '2026_1-9月金额_万': a} for s, n, a in sorted(made, key=lambda x: -x[2])]}
    json.dump(idx, open(os.path.join(OUTDIR, '_索引.json'), 'w', encoding='utf-8'), ensure_ascii=False, indent=1)
    print('生成 %d 个销售员文件 → %s' % (len(made), OUTDIR))
    for s, n, a in sorted(made, key=lambda x: -x[2])[:12]:
        print('   %-8s %3d 客户 ｜ 2026(1-9月) %8.2f 万' % (s, n, a))
    print()
    lz = os.path.join(OUTDIR, '刘子研.json')
    if os.path.exists(lz):
        o = json.load(open(lz, encoding='utf-8'))
        print('刘子研：%d 客户 ｜ 样例（前 3）:' % o['_客户数'])
        for c in o['客户'][:3]:
            print('   %s ｜ 2025 %s 元 ｜ 2026(1-9月) %s 元 ｜ 主销货号 %s' % (
                c['客户'], c['年度'].get('2025', {}).get('金额'), c['年度'].get('2026', {}).get('金额'),
                (c['主销货号TOP5'][0]['物料'][:24] if c['主销货号TOP5'] else '—')))


if __name__ == '__main__':
    main()
