#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Q3汇报 ⑤ 竞品情报台账
从 Q3 飞书活动原文（field_b99055）提取竞品品牌 + 优势/价格/政策证据，逐条附原文链接。
确定性筛选：按优势语义关键词打分 -> 按 (客户, 首60字) 去重 -> 每品牌取 TOP N。
"""
import json, os, re
from collections import Counter

ROOT = os.path.expanduser("~/Desktop/Hermes输出-工作类")
OUTD = os.path.join(ROOT, "2026年3季度汇报", "_汇总")
ACT_URL = "https://project.feishu.cn/baoyu/workitem/%s"
TOPN = 10

SCORE_KW = [
    ("优势", 5), ("优于", 5), ("更好", 4), ("效果好", 4), ("性能", 4), ("稳定", 4),
    ("灵敏度", 4), ("特异性", 3), ("便宜", 4), ("低价", 4), ("降价", 4), ("价格", 3),
    ("政策", 3), ("套餐", 4), ("促销", 4), ("积分", 3), ("送", 2), ("返利", 4),
    ("让利", 4), ("折扣", 4), ("战略合作", 5), ("深度合作", 5), ("投放", 4), ("绑定", 4),
    ("不如", 5), ("抢走", 5), ("替换", 2), ("测试", 1), ("对比", 2), ("综合", 2),
    ("体系", 1), ("导入", 3), ("存量", 2), ("粘性", 4), ("免费", 3), ("试用", 2),
]

def score(t):
    return sum(w for k, w in SCORE_KW if k in t)

def main():
    d = json.load(open(os.path.join(OUTD, "Q3活动客诉竞品.json")))
    h1 = json.load(open(os.path.join(OUTD, "人员提炼_H1.json")))

    ledger = {}
    for brand, v in d["competitors"].items():
        seen, rows = set(), []
        for h in v["hits"]:
            if len(h["text"]) < 12:
                continue
            key = (h["customer"], h["text"][:60])
            if key in seen:
                continue
            seen.add(key)
            rows.append({**h, "score": score(h["text"])})
        rows.sort(key=lambda x: (-x["score"], x["date"]), )

        # 保留最长的版本（同一 (customer, prefix) 取信息量最大）
        best = {}
        for r in rows:
            k = (r["customer"], r["text"][:60])
            if k not in best or len(r["text"]) > len(best[k]["text"]):
                best[k] = r
        rows = sorted(best.values(), key=lambda x: -x["score"])[:TOPN]

        ledger[brand] = {
            "mentions": v["count"],
            "sp_readers": dict(Counter(h["sp"] for h in v["hits"]).most_common(8)),
            "evidence": [{
                "date": r["date"], "sp": r["sp"], "customer": r["customer"],
                "text": r["text"].strip(), "work_item_id": r["work_item_id"],
                "url": ACT_URL % r["work_item_id"], "score": r["score"],
            } for r in rows],
        }

    # H1 报告内竞品板块（结构化）—— 品牌名先归一，再与 Q3 台账对齐
    ALIAS = [
        (("诺唯赞", "诺维赞", "诺威赞", "Vazyme"), "诺唯赞"),
        (("翌圣", "Yeasen", "翊圣"), "翌圣"),
        (("瀚海",), "瀚海新酶"),
        (("全式金", "TransGen"), "全式金"),
        (("康为",), "康为世纪"),
        (("迈迪安", "MDX", "Meridian"), "迈迪安"),
        (("艾科瑞",), "艾科瑞"),
        (("Takara", "TAKARA", "宝生物", "宝日医"), "Takara宝生物"),
        (("赛默飞", "Thermo"), "赛默飞"),
        (("近岸",), "近岸蛋白"),
        (("爱博泰克", "ABclonal"), "爱博泰克"),
        (("菲鹏",), "菲鹏"),
        (("天根",), "天根"),
        (("索莱宝",), "索莱宝"),
        (("碧云天",), "碧云天"),
        (("NEB",), "NEB"),
        (("罗氏", "Roche"), "罗氏Roche"),
        (("雅酶",), "雅酶"),
        (("新赛美",), "新赛美"),
        (("金诺美",), "金诺美"),
        (("白垩纪",), "白垩纪"),
        (("赛诺",), "张家口赛诺"),
        (("tolobio",), "tolobio"),
        (("易思得",), "易思得"),
        (("Genstar",), "Genstar"),
        (("擎科",), "擎科"),
        (("Bio-Rad", "BioRad"), "Bio-Rad"),
    ]

    def norm(b):
        for keys, canon in ALIAS:
            for k in keys:
                if k.lower() in b.lower():
                    return canon
        return b.strip()

    report_comp = {}
    for p in h1["people"]:
        for c in p.get("competitors", []) or []:
            b = c.get("brand", "").strip()
            if not b:
                continue
            b = norm(b)
            report_comp.setdefault(b, []).append({
                "from": p["name"], "product": c.get("product", ""),
                "price": c.get("price", ""), "note": c.get("note", ""),
                "source": c.get("source", ""),
            })

    # 合并视图：品牌 -> Q3活动提及数 + H1报告记录数
    merged = {}
    for b in set(list(ledger.keys()) + list(report_comp.keys())):
        merged[b] = {
            "q3_mentions": ledger.get(b, {}).get("mentions", 0),
            "q3_evidence": len(ledger.get(b, {}).get("evidence", [])),
            "h1_records": len(report_comp.get(b, [])),
        }
    merged = dict(sorted(merged.items(),
                         key=lambda x: -(x[1]["q3_mentions"] * 2 + x[1]["h1_records"])))

    out = {
        "_meta": {
            "generated": "2026-10-01",
            "scope": "2026 Q3（7-9月）飞书活动原文命中 + 2026半年度汇报竞品板块",
            "act_url": ACT_URL % "<work_item_id>",
            "method": "优势语义加权打分 + (客户,前60字)去重 + 每品牌TOP%d；品牌别名已归一" % TOPN,
            "caution": "命中为关键词匹配，含少量同义/误匹配；引用一律为原文，未改写。",
        },
        "merged_index": merged,
        "q3_activity_ledger": dict(sorted(ledger.items(), key=lambda x: -x[1]["mentions"])),
        "h1_report_competitors": dict(sorted(report_comp.items(), key=lambda x: -len(x[1]))),
    }
    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 活动台账：品牌 / 提及数 / 证据条 ==")
    for b, v in out["q3_activity_ledger"].items():
        print("  %-16s %4d  %2d" % (b, v["mentions"], len(v["evidence"])))
    print("\n== H1 报告竞品板块：品牌 / 记录数 ==")
    for b, v in out["h1_report_competitors"].items():
        print("  %-20s %2d" % (b, len(v)))

if __name__ == "__main__":
    main()
