import sys, io, json, re
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")

import os
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.dirname(SCRIPT_DIR)

with open(os.path.join(PROJECT_ROOT, "data", "raw-messages", "all_messages_combined.json"), "r", encoding="utf-8") as f:
    data = json.load(f)

feishu_re = re.compile(r"https?://[a-zA-Z0-9.-]+\.feishu\.cn/(?:wiki|docx)/[A-Za-z0-9]+")
file_re = re.compile(r"\[文件\]\s+(.+?)\s+fileId:\s+(\S+)")
kimi_re = re.compile(r"https?://[a-zA-Z0-9.-]+\.ok\.kimi\.link/\S*")
weixin_re = re.compile(r"https?://mp\.weixin\.qq\.com/\S+")
github_re = re.compile(r"https?://github\.com/\S+")

# Person registry
persons = {}
# Link registry
all_links = []
# File registry
all_files = []
# Knowledge entities
entities = []
# Relationships
relationships = []

def get_or_create_person(name, dingtalk_id=None):
    if name not in persons:
        persons[name] = {"name": name, "dingtalk_id": dingtalk_id, "groups": [], "contributions": 0, "topics": set()}
    persons[name]["contributions"] += 1
    if dingtalk_id:
        persons[name]["dingtalk_id"] = dingtalk_id
    return persons[name]

for group_name, msgs in data.items():
    group_label = "dc战略问题研究院" if group_name == "dc" else "创新组"
    
    for msg in msgs:
        content = msg.get("content", "")
        sender = msg.get("sender", "unknown")
        time = msg.get("createTime", "")
        sender_id = msg.get("senderOpenDingTalkId", "")
        
        person = get_or_create_person(sender, sender_id)
        if group_label not in person["groups"]:
            person["groups"].append(group_label)
        
        # Extract feishu links
        for link in feishu_re.findall(content):
            entry = {
                "url": link, "sender": sender, "time": time, "group": group_label,
                "type": "wiki" if "/wiki/" in link else "docx",
                "domain": link.split("/")[2]
            }
            # Try to get context from surrounding text
            ctx = content.replace(link, "").strip()[:100]
            if ctx:
                entry["context"] = ctx
            all_links.append(entry)
        
        # Extract file attachments
        fm = file_re.search(content)
        if fm:
            all_files.append({
                "name": fm.group(1), "fileId": fm.group(2),
                "sender": sender, "time": time, "group": group_label
            })
        
        # Extract Kimi links
        for link in kimi_re.findall(content):
            desc = content.split("https")[0].strip()[:100]
            all_links.append({
                "url": link, "sender": sender, "time": time, "group": group_label,
                "type": "kimi", "domain": "kimi.link", "context": desc
            })
        
        # Extract WeChat articles
        for link in weixin_re.findall(content):
            desc = content.split("https")[0].strip()[:100]
            all_links.append({
                "url": link, "sender": sender, "time": time, "group": group_label,
                "type": "weixin_article", "domain": "mp.weixin.qq.com", "context": desc
            })

# Deduplicate links by URL
unique_links = {}
for link in all_links:
    url = link["url"]
    if url not in unique_links:
        unique_links[url] = {**link, "shared_count": 1}
    else:
        unique_links[url]["shared_count"] += 1

# Build knowledge graph
graph = {
    "metadata": {
        "generated": "2026-06-02",
        "groups": ["dc战略问题研究院", "创新组"],
        "time_range": "2026-05-01 ~ 2026-06-02",
        "total_messages": len(data["dc"]) + len(data["cx"])
    },
    "persons": {},
    "documents": [],
    "files": [],
    "topics": [],
    "relationships": []
}

# Process persons
for name, p in persons.items():
    graph["persons"][name] = {
        "name": name,
        "groups": p["groups"],
        "contributions": p["contributions"],
        "dingtalk_id": p.get("dingtalk_id", "")
    }

# Process documents (feishu links)
domain_map = {
    "dianchukeji.feishu.cn": "dianchukeji (公司飞书)",
    "fcnlycv6dd0w.feishu.cn": "fcnlycv6dd0w (研究组飞书)",
    "ocnmca6f1o0p.feishu.cn": "ocnmca6f1o0p (另一飞书空间)",
    "my.feishu.cn": "my.feishu.cn (个人飞书)"
}

for url, link in unique_links.items():
    doc = {
        "url": url,
        "type": link["type"],
        "domain": domain_map.get(link["domain"], link["domain"]),
        "shared_by": link["sender"],
        "first_shared": link["time"],
        "group": link["group"],
        "context": link.get("context", ""),
        "share_count": link["shared_count"]
    }
    graph["documents"].append(doc)

# Process files
seen_files = set()
for f in all_files:
    key = f["fileId"]
    if key not in seen_files:
        seen_files.add(key)
        graph["files"].append(f)

# Build topic clusters
# Group documents by sender and domain to identify topic clusters
sender_domains = {}
for doc in graph["documents"]:
    key = (doc["shared_by"], doc["domain"])
    if key not in sender_domains:
        sender_domains[key] = []
    sender_domains[key].append(doc)

# Identify main topics based on content analysis
topics = [
    {
        "name": "《我的花园世界》深度研究",
        "description": "围绕《我的花园世界》的全方位研究，包括产品机制、商业化、资源经济、竞品对比",
        "key_people": ["李志健", "黄静雯", "陈楚真", "傅明游"],
        "documents_count": 0,
        "files": ["主报告-我的花园世界.html", "2026-05-25_report_my_garden_world_us_project.html",
                  "花园项目对策划的启示.md", "进一步的思考.md", "花园世界产品策略_GOS补充信息.md",
                  "花园世界等相关产品25.10.28.xlsx"],
        "key_concepts": ["低压经营", "极致消耗", "非战斗GVG", "社交拉氪", "大通服", "腰部底座放大"]
    },
    {
        "name": "云湖工作室项目选择",
        "description": "广州云湖工作室第一个转型项目的方向选择分析",
        "key_people": ["黄静雯"],
        "documents_count": 0,
        "files": ["2026-05-yunhu-project-selection-strategy-report.html"],
        "key_concepts": ["2个月MVP", "AI美术适配", "素材CPI验证", "欧美化花园经营"]
    },
    {
        "name": "Game Analyst Agent 工具",
        "description": "通用产品分析自动化工具，自动探索游戏界面、提取机制与数值",
        "key_people": ["黄静雯"],
        "documents_count": 0,
        "files": ["game-analyst-agent-manual.html", "game-analyst-agent.zip"],
        "key_concepts": ["自动界面探索", "pHash去重", "9级决策链", "多游戏对比", "决策报告生成"]
    },
    {
        "name": "战略思维与方法论",
        "description": "李志健关于幸存者偏差、筹码管理、生长逻辑的战略反思",
        "key_people": ["李志健"],
        "documents_count": 0,
        "files": ["取败之道.md", "模型报告.html"],
        "key_concepts": ["幸存者偏差", "筹码管理", "正期望博弈", "生长逻辑", "非对称博弈"]
    },
    {
        "name": "AI落地与组织变革",
        "description": "AI在游戏研发中的实际落地、效率提升与组织变革讨论",
        "key_people": ["李志健", "林峰", "汪雄军", "上官成", "安东"],
        "documents_count": 0,
        "files": [],
        "key_concepts": ["AI军备竞赛", "端到端提效", "组织变革", "AI工作小组"]
    },
    {
        "name": "创新组日报与研发进展",
        "description": "创新组成员的每日工作日报，涵盖二合类游戏研发、AI工具使用",
        "key_people": ["王雨默", "韦译", "刘鹏", "卓泽", "徐锐"],
        "documents_count": 0,
        "files": ["工作流总结-王雨默.html"],
        "key_concepts": ["二合类游戏", "AI关卡生成", "UI编辑器", "数值平衡", "竞品分析"]
    },
    {
        "name": "战略组日报与知识产出",
        "description": "战略研究组成员每日提交的研究日报",
        "key_people": ["黄静雯", "陈楚真", "张家振", "夏莲", "莫润麟", "胡辉俊", "汪季"],
        "documents_count": 0,
        "files": [],
        "key_concepts": ["竞品拆解", "知识卡片", "MECH/REPORT/ORG卡片", "Agent架构"]
    }
]

graph["topics"] = topics

# Build relationships
rels = []

# Person -> Topic relationships
for topic in topics:
    for person in topic["key_people"]:
        rels.append({
            "source": person, "target": topic["name"],
            "type": "contributes_to", "weight": 1
        })

# Person -> Person relationships (co-contribution in same group)
for group_name, msgs in data.items():
    group_label = "dc战略问题研究院" if group_name == "dc" else "创新组"
    msg_senders = set(m.get("sender", "") for m in msgs)
    for p1 in msg_senders:
        for p2 in msg_senders:
            if p1 < p2:
                rels.append({
                    "source": p1, "target": p2,
                    "type": "co_group_member",
                    "group": group_label, "weight": 1
                })

graph["relationships"] = rels

# Save graph
with open(os.path.join(PROJECT_ROOT, "output", "knowledge-graph", "knowledge_graph.json"), "w", encoding="utf-8") as f:
    json.dump(graph, f, ensure_ascii=False, indent=2, default=str)

# Print summary
print("=== Knowledge Graph Summary ===")
print("Persons: %d" % len(graph["persons"]))
print("Documents (feishu links): %d" % len(graph["documents"]))
print("Files: %d" % len(graph["files"]))
print("Topics: %d" % len(graph["topics"]))
print("Relationships: %d" % len(graph["relationships"]))

print("\n=== Persons ===")
for name, p in sorted(graph["persons"].items(), key=lambda x: -x[1]["contributions"]):
    print("  %s: %d msgs, groups=%s" % (name, p["contributions"], ", ".join(p["groups"])))

print("\n=== Documents by Domain ===")
domain_counts = {}
for doc in graph["documents"]:
    d = doc["domain"]
    domain_counts[d] = domain_counts.get(d, 0) + 1
for d, c in sorted(domain_counts.items(), key=lambda x: -x[1]):
    print("  %s: %d links" % (d, c))

print("\n=== Files ===")
for f in graph["files"]:
    print("  %s (by %s, %s)" % (f["name"], f["sender"], f["time"]))

print("\n=== Topics ===")
for t in graph["topics"]:
    print("  %s: %s" % (t["name"], t["description"][:60]))
    print("    Key people: %s" % ", ".join(t["key_people"]))
    print("    Key concepts: %s" % ", ".join(t["key_concepts"][:4]))

print("\nSaved to knowledge_graph.json")

