#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Q3汇报 ②③⑤ 数据提取
② 本季度每个销售的飞书活动 / 客诉
③ 关键客诉与风险事项（附飞书原文链接）
⑤ 主要竞争对手品牌及其优势（附提及该信息的飞书活动原文链接）
数据源：数据/daily_activities_mcp.json、数据/mcp_complaints.json
链接口径：活动 https://project.feishu.cn/baoyu/workitem/<work_item_id>
         客诉 https://project.feishu.cn/br-shgl/khts/detail/<id>
"""
import json, os, re, sys
from collections import defaultdict, Counter

ROOT = os.path.expanduser("~/Desktop/Hermes输出-工作类")
OUTD = os.path.join(ROOT, "2026年3季度汇报", "_汇总")
Q_START, Q_END = "2026-07-01", "2026-09-30"
ACT_URL = "https://project.feishu.cn/baoyu/workitem/%s"
CMP_URL = "https://project.feishu.cn/br-shgl/khts/detail/%s"

BRANDS = [
    ("诺唯赞", ["诺唯赞", "诺维赞", "诺威赞", "Vazyme", "vazyme", "NWZ", "nwz"]),
    ("翌圣",   ["翌圣", "Yeasen", "yeasen", "翊圣"]),
    ("全式金", ["全式金", "TransGen", "transgen"]),
    ("瀚海新酶", ["瀚海"]),
    ("康为世纪", ["康为", "康为世纪"]),
    ("艾科瑞", ["艾科瑞", "Accurate"]),
    ("迈迪安", ["迈迪安", "MDX", "Meridian"]),
    ("菲鹏",   ["菲鹏", "Fapon"]),
    ("近岸蛋白", ["近岸"]),
    ("Takara宝生物", ["Takara", "TAKARA", "takara", "宝生物", "宝日医"]),
    ("赛默飞", ["赛默飞", "Thermo", "thermo", "Invitrogen", "invitrogen"]),
    ("雅酶",   ["雅酶", "Yeasen雅酶"]),
    ("新赛美", ["新赛美"]),
    ("爱博泰克", ["爱博泰克", "ABclonal", "abclonal"]),
    ("百时美", ["百时美"]),
    ("白垩纪", ["白垩纪"]),
    ("张家口赛诺", ["张家口赛诺", "赛诺"]),
    ("tolobio", ["tolobio", "ToloBio"]),
    ("易思得", ["易思得"]),
    ("金诺美", ["金诺美"]),
    ("天根",   ["天根", "TIANGEN"]),
    ("索莱宝", ["索莱宝", "Solarbio"]),
    ("罗氏Roche", ["罗氏", "Roche"]),
    ("Bio-Rad", ["Bio-Rad", "Biorad", "伯乐"]),
    ("NEB",    ["NEB"]),
    ("碧云天", ["碧云天"]),
    ("擎科",   ["擎科"]),
    ("生工",   ["生工"]),
    ("Genstar", ["Genstar"]),
    ("安徽通用生物", ["通用生物"]),
]

def q3_activities():
    d = json.load(open(os.path.join(ROOT, "数据/daily_activities_mcp.json")))
    return [x for x in d["items"] if Q_START <= x.get("start_time", "") <= Q_END]

def all_complaints():
    return json.load(open(os.path.join(ROOT, "数据/mcp_complaints.json")))["items"]

def main():
    acts = q3_activities()
    cmps = all_complaints()
    q3c = [c for c in cmps if Q_START <= c.get("created", "") <= Q_END]

    # ---------- ② 活动 per 销售 ----------
    per = defaultdict(lambda: {"total": 0, "by_month": Counter(), "by_customer": Counter(), "items": []})
    for a in acts:
        name = (a.get("owner") or {}).get("name_cn", "?")
        p = per[name]
        p["total"] += 1
        p["by_month"][a["start_time"][:7]] += 1
        cust = (a.get("field_5f20fc") or {}).get("label", "")
        if cust:
            p["by_customer"][cust] += 1

    # ---------- ③ 客诉 ----------
    RANK = {"critical": 4, "high": 3, "medium": 2, "normal": 1, "": 0}
    q3c_sorted = sorted(q3c, key=lambda c: (-RANK.get(c.get("urgency", ""), 0), c.get("created", "")))
    cmp_by_creator = Counter(c.get("creator", "?") for c in q3c)
    open_cmps = [c for c in q3c if c.get("status") != "结束"]

    # ---------- ⑤ 竞品 ----------
    comp = {}
    for brand, keys in BRANDS:
        hits = []
        for a in acts:
            txt = a.get("field_b99055") or ""
            if not txt:
                continue
            for k in keys:
                if k in txt:
                    hits.append({
                        "date": a["start_time"],
                        "sp": (a.get("owner") or {}).get("name_cn", ""),
                        "customer": (a.get("field_5f20fc") or {}).get("label", ""),
                        "text": txt,
                        "work_item_id": a.get("work_item_id"),
                        "url": ACT_URL % a.get("work_item_id"),
                        "kw": k,
                    })
                    break
        if hits:
            comp[brand] = {"count": len(hits), "hits": hits}

    out = {
        "_meta": {
            "generated": "2026-10-01",
            "quarter": f"{Q_START} ~ {Q_END}",
            "act_url": ACT_URL % "<work_item_id>",
            "cmp_url": CMP_URL % "<id>",
            "sources": ["数据/daily_activities_mcp.json", "数据/mcp_complaints.json"],
        },
        "q3_activities": {
            "total": len(acts),
            "by_month": dict(Counter(a["start_time"][:7] for a in acts)),
            "by_sales": {k: {"total": v["total"], "by_month": dict(v["by_month"])}
                         for k, v in sorted(per.items(), key=lambda x: -x[1]["total"])},
            "by_sales_customers": {k: dict(v["by_customer"].most_common(15))
                                   for k, v in per.items()},
        },
        "q3_complaints": {
            "total": len(q3c),
            "total_all": len(cmps),
            "by_urgency": dict(Counter(c.get("urgency", "") for c in q3c)),
            "by_area": dict(Counter(c.get("area", "") for c in q3c)),
            "by_creator": dict(cmp_by_creator.most_common()),
            "not_closed": len(open_cmps),
            "items": [{
                "id": c["id"], "name": c["name"], "created": c["created"],
                "days": c.get("days"), "urgency": c.get("urgency"),
                "area": c.get("area"), "status": c.get("status"),
                "customer": c.get("customer"), "creator": c.get("creator"),
                "operator": c.get("operator"), "node": c.get("node"),
                "url": CMP_URL % c["id"],
            } for c in q3c_sorted],
        },
        "competitors": {b: {"count": v["count"], "hits": v["hits"]} for b, v in
                        sorted(comp.items(), key=lambda x: -x[1]["count"])},
    }
    os.makedirs(OUTD, exist_ok=True)
    p = os.path.join(OUTD, "Q3活动客诉竞品.json")
    json.dump(out, open(p, "w"), ensure_ascii=False, indent=1)
    print("WROTE", p, os.path.getsize(p), "bytes")

    # 摘要打印
    print("\n== ② Q3活动 %d 条 / %d 人 ==" % (len(acts), len(per)))
    for k, v in sorted(per.items(), key=lambda x: -x[1]["total"]):
        print("  %-6s %4d  %s" % (k, v["total"], dict(v["by_month"])))
    print("\n== ③ Q3客诉 %d 条（全量 %d）；未结束 %d ==" % (len(q3c), len(cmps), len(open_cmps)))
    print("  by_urgency:", dict(Counter(c.get("urgency","") for c in q3c)))
    print("  by_area:", dict(Counter(c.get("area","") for c in q3c)))
    print("  by_creator:", dict(cmp_by_creator.most_common()))
    print("\n== ⑤ 竞品提及 TOP ==")
    for b, v in sorted(comp.items(), key=lambda x: -x[1]["count"]):
        print("  %-16s %3d" % (b, v["count"]))

if __name__ == "__main__":
    main()
