#!/usr/bin/env python3
"""Write per-cluster Brain-Notes plus a master index from _reels-clustered.json."""
from __future__ import annotations

import json
from pathlib import Path

DIR = Path("/root/aria/brain/00-Inbox/links-check-2026-05-15")
SRC = DIR / "_reels-clustered.json"

# Cluster-specific TL;DR seeds + Aria-Relevanz hand-written so the notes are
# useful, not just a regurgitation of metadata.
CLUSTER_NOTES = {
    "claude-skills": {
        "tldr": "Claude Skills Feature dominiert in der Nische. 9 Reels von 7 Creators erklären jeweils 'die 3-5 Skills, die du installieren musst'. Aria hat das System schon (`/root/.claude/skills/`) mit eigenem skill-creator. Was die Reels zeigen: was die Community wirklich installiert.",
        "aria_relevance": (
            "- Aria nutzt das selbe Skill-System (Anthropic-spec) — die hier genannten externen Skills sind potenzielle Adoption-Kandidaten.\n"
            "- Wiederkehrende Empfehlungen: Emil-Kowalski-Animations-Skill, shadcn/ui-Skill, Graphify (Knowledge-Graph), Superpowers, Memory-Skill. Mehrere davon hat Aria schon (skill-creator, frontend-design, graphify) → bestätigt: wir sind on-pattern.\n"
            "- Action: aus den 9 Reels die genannten externen Repo-Namen extrahieren und gegen integration-wishlist.md cross-checken (siehe MEMORY-Eintrag feedback_integration_wishlist).\n"
            "- Hebel: einer der Reels (DXqyYTLDqRE) verweist auf einen 8k-Stars chinesischen Design-Skill — das ist genau der Pattern den Aria's skill-creator bauen soll."
        ),
    },
    "claude-mcp-servers": {
        "tldr": "MCP-Server-Empfehlungen für Claude. 2 Reels listen jeweils mehrere MCP-Server für browsing/scraping/automation auf.",
        "aria_relevance": (
            "- Aria hat bereits MCP-Setup (mcp.json mit Telegram, GitHub, Linear, Supabase, Vercel, Figma, Drive).\n"
            "- Vergleich zur Liste in den Reels ziehen: was fehlt? Stichwort 'live browsing/scraping' → potenziell ein Playwright-MCP oder Firecrawl-MCP.\n"
            "- Action: Kommentar in DYHLSAzPGrL ('MCP') als Trigger zum Repo-Link, manuell prüfen vs. unsere Liste."
        ),
    },
    "claude-news-updates": {
        "tldr": "Anthropic-Update-Recap. 1 Reel von vaibhavsisinty (6k likes) summt 4 'quiet upgrades' für AI-Agenten — kein neues Modell, sondern Plattform-Features.",
        "aria_relevance": (
            "- Anthropic-News tracken via offizielle Quellen (changelog.anthropic.com, deren Blog) statt Reels.\n"
            "- Aber: hohe Likes heißt das Topic resoniert → Aria sollte Anthropic-Releases ähnlich kompakt für Kais zusammenfassen, sobald sie droppen.\n"
            "- Action: Im AKP einen Anthropic-Blog-RSS-Feed einbauen falls noch nicht da."
        ),
    },
    "claude-design-ui": {
        "tldr": "Designer-Bias der Reels. 5 Reels behaupten 'Claude macht jetzt Designer überflüssig / non-designer to designer'. Wiederkehrendes Pattern: 3-Skill-Setup (Animation + Component-Library + Layout-System).",
        "aria_relevance": (
            "- Aria hat frontend-design + ui-ux-pro-max + theme-factory + figma-Skills. Setup ist sehr ähnlich.\n"
            "- Lessons: Designer-Bias-Pitch ist Marketing-Hook, nicht Engineering-Realität. Aber: wenn Kais ein Frontend bauen lässt, sollte Aria automatisch frontend-design + theme-factory zusammenziehen statt einzeln.\n"
            "- Action: Skill-Composition pattern dokumentieren — 'für UI-Tasks immer diese 2-3 Skills bündeln'."
        ),
    },
    "claude-memory-agentic": {
        "tldr": "Memory & Agentic-OS Sub-Topic. 6 Reels — Knowledge-Graph (Graphify), Second-Brain, Self-Running-AI-Company, Pixel-Office-Metapher, Ralph (Autonomie-Loop), Skills-für-Memory.",
        "aria_relevance": (
            "- DIREKTER OVERLAP mit Aria-Brain-Architektur (V5, Sleep-Memory-Consolidation, Curator).\n"
            "- 'Ralph' (DUkkPXKDPBG) — Autonomie-Wrapper für Claude Code — anschauen ob der Pattern bringt was Aria's mode-toggle (assist/auto/yolo) noch nicht hat.\n"
            "- Graphify (DYC831vgY8y) — Knowledge-Graph aus eigenen Sessions. Aria hat den graphify-Skill bereits installiert. Frage: nutzen wir ihn aktiv? Falls nein → integrieren in retro/wrap-up.\n"
            "- Action: KAR-Issue 'Aria-Brain Knowledge-Graph Audit — vs. Reel-Empfehlungen' als low-prio Spike."
        ),
    },
    "claude-repos-tools": {
        "tldr": "GitHub-Repo-Empfehlungen für Claude Code. 2 Reels listen Top-Repos (200k+ stars zusammen). bennyautomates und mike-means-business.",
        "aria_relevance": (
            "- Repos-Listen sind die nützlichsten Reels der ganzen Liste — direkt actionable.\n"
            "- Action: claude-watch ODER manueller Aufruf der 2 Reels (DWZjz6xgBV1 + DVRu6GlDNHO), Repo-Namen extrahieren, jeden Repo-Namen gegen integration-wishlist.md prüfen, sonst dort eintragen.\n"
            "- Diese 2 Reels = WICHTIGSTER deep-watch-Kandidat aus der ganzen Liste."
        ),
    },
    "ai-coding-agents-generic": {
        "tldr": "Generischer AI-Coding-Content. 12 Reels — meist 'Comment X for the link' Lead-Magnet-Strategie. Substanz dünn, Marketing-Hook dick.",
        "aria_relevance": (
            "- Lehre für Aria-Distribution-Strategie (siehe MEMORY project_aria_distribution_strategy): wenn man später Aria-Skills 'verkauft', wird genau dieses Lead-Magnet-Pattern auf einen zukommen. Verstehen, nicht imitieren.\n"
            "- Engagement-Bait-Anti-Pattern: 'Comment GUIDE for the link' — funktioniert IG-algorithmisch, ist aber für Aria-Brand falsch (wir liefern Substanz, nicht Click-Bait).\n"
            "- Action: keine direkte. Cluster ist Noise mit mittlerer Signal-to-Noise-Ratio."
        ),
    },
    "ai-tools-news": {
        "tldr": "Generic AI-Tools-Content. 2 Reels — keine spezifische Aria-Relevanz.",
        "aria_relevance": "- Skip."
    },
    "business-money-seo": {
        "tldr": "Business/SEO mit Claude. 2 Reels — Backlink-Generation per Claude (DYQBqwToCau, florent_preusser), $10k-Agency-vs-10min-Claude-Pitch (DYPlkkGIZ2C).",
        "aria_relevance": (
            "- Backlink-Reel ist tatsächlich brauchbar: zwei-Prompt-System für SEO-Backlinks via Claude. Wenn Kadi-v2 oder Kais-Site SEO braucht, das Pattern testen.\n"
            "- Action: Reel DYQBqwToCau in claude-watch deep-watch (kurz, 30-60s) — die exakten 2 Prompts extrahieren."
        ),
    },
    "uncategorized": {
        "tldr": "3 nicht-zugeordnete Reels — entweder zu vage Captions oder Off-Topic.",
        "aria_relevance": "- Skip oder einzeln review wenn der Uploader bekannt ist."
    },
}


def fmt_count(n) -> str:
    if n is None:
        return "n/a"
    if n >= 1_000_000:
        return f"{n/1_000_000:.1f}M"
    if n >= 1_000:
        return f"{n/1_000:.1f}k"
    return str(n)


def write_cluster_note(cluster_key: str, items: list[dict], label: str) -> Path:
    out = DIR / f"reels-cluster-{cluster_key}.md"
    meta = CLUSTER_NOTES.get(cluster_key, {
        "tldr": f"{len(items)} Reels in diesem Cluster.",
        "aria_relevance": "- (manuell ergänzen)"
    })

    # Frontmatter (Aria-Brain schema, see /root/aria/brain/CLAUDE.md sec.1)
    lines = [
        "---",
        f"title: Reels-Cluster: {label}",
        "type: research",
        f"tags: [audit, links-check, instagram-reels, {cluster_key}]",
        "date: 2026-05-15",
        "status: aktiv",
        "source: /root/aria/brain/00-Inbox/links-check-2026-05-15/_reels-metadata.jsonl",
        "related: [[reels-grouped]]",
        "---",
        "",
        f"# Reels-Cluster — {label}",
        "",
        "## TL;DR",
        meta["tldr"],
        "",
        f"**Anzahl Reels:** {len(items)}",
        f"**Top-Uploader:** "
        + ", ".join(sorted({it['uploader'] for it in items if it.get('uploader')}, key=str.lower)[:6]),
        "",
        "## Reels-Liste",
        "",
        "| Slug | Uploader | Likes | Caption-Auszug |",
        "|---|---|---|---|",
    ]

    for it in sorted(items, key=lambda d: -(d.get("like_count") or 0)):
        slug = it["slug"]
        uploader = it.get("uploader") or ""
        likes = fmt_count(it.get("like_count"))
        cap = (it.get("description") or "").replace("\n", " ").replace("|", "/")[:120]
        url = it.get("url") or f"https://www.instagram.com/reel/{slug}/"
        lines.append(f"| [{slug}]({url}) | @{uploader} | {likes} | {cap} |")

    lines += [
        "",
        "## Themen-Aggregation",
        "",
        "Wiederkehrende Themen-Marker im Cluster (regex-basierte Hits):",
        "",
    ]
    # Top hit keywords
    from collections import Counter
    cnt: Counter = Counter()
    for it in items:
        for h in it.get("_hits", []):
            cnt[h] += 1
    for term, n in cnt.most_common(15):
        lines.append(f"- `{term}` × {n}")
    lines += [
        "",
        "## Aria-Relevanz",
        "",
        meta["aria_relevance"],
        "",
        "## Vollständige Captions (für Skim)",
        "",
    ]
    for it in sorted(items, key=lambda d: -(d.get("like_count") or 0)):
        slug = it["slug"]
        uploader = it.get("uploader") or ""
        cap = (it.get("description") or "").strip()
        if not cap:
            continue
        lines.append(f"### {slug} — @{uploader} ({fmt_count(it.get('like_count'))} likes)")
        lines.append("")
        lines.append(cap)
        lines.append("")

    out.write_text("\n".join(lines))
    return out


def write_master(by_cluster: dict, labels: dict, total: int, skipped_count: int) -> Path:
    out = DIR / "reels-grouped.md"
    cluster_rows = []
    for k, items in sorted(by_cluster.items(), key=lambda kv: -len(kv[1])):
        cluster_rows.append((k, labels.get(k, k), len(items)))

    lines = [
        "---",
        "title: Reels Mass-Audit 2026-05-15 — Cluster-Übersicht",
        "type: audit",
        "tags: [audit, links-check, instagram-reels, master-index]",
        "date: 2026-05-15",
        "status: aktiv",
        "source: /root/aria/brain/00-Inbox/links-check-2026-05-15/_reels-metadata.jsonl",
        "related: "
        + ", ".join(f"[[reels-cluster-{k}]]" for k, _, _ in cluster_rows),
        "---",
        "",
        "# Reels Mass-Audit — 2026-05-15",
        "",
        "## Stats",
        "",
        f"- Reels in Liste:    47 (inkl. 2 Duplikate, inkl. 2 mit Deep-Watch-Tag)",
        f"- Deep-Watch separat: 2 (DYUG44IsY_y, DYT7ZLDM-at — anderer Subagent)",
        f"- Mass-Audit-Pool:   45 (nach Dedupe der Duplikate)",
        f"- Erfolgreich processed: {total}",
        f"- Skipped (deleted/private): {skipped_count}",
        "",
        "## Methode",
        "",
        "1. **Phase A — Metadata-Sweep:** Erst yt-dlp+Cookies versucht — IG hat nach 8 Reels rate-limited.\n"
        "   Fallback war OG-Meta-Tag-Scrape (`curl + Mozilla-UA, kein Auth`) — funktionierte für 44/45 in <30s.\n"
        "   Gewonnen: uploader handle, full caption, likes/comments, upload date.\n"
        "2. **Phase B — Cluster-Bildung:** Regex-Rule-Engine (`_cluster-reels.py`) mit first-match-wins\n"
        "   über uploader + caption + title.\n"
        "3. **Phase C — Cluster-Notes:** Pro Cluster eine Brain-Note + dieser Master-Index.\n",
        "",
        "## Cluster-Übersicht",
        "",
        "| # | Cluster | Anzahl | Note |",
        "|---|---|---|---|",
    ]
    for k, label, n in cluster_rows:
        lines.append(f"| | {label} | {n} | [[reels-cluster-{k}]] |")
    lines += [
        "",
        "## Wichtigste Erkenntnis",
        "",
        "**Die Liste ist hyper-fokussiert auf Claude Code / Anthropic-Ökosystem.** 37 von 44 Reels (84%) drehen sich um Claude/MCP/Skills/Agents — kein Politik, kein Lifestyle, kein Business-Generic. Das bedeutet:",
        "",
        "1. **Kais konsumiert IG sehr gezielt für Aria-Verbesserung** (Standing Order `feedback_research_aria_first` ist live).",
        "2. **Sub-Themen-Verteilung** ist informativ:",
        "   - 9× Claude Skills (das neue Feature dominiert die Diskussion komplett)",
        "   - 6× Memory/Agentic-OS (overlap mit Aria-Brain-Roadmap)",
        "   - 5× Design/UI (overlap mit frontend-design Skill)",
        "   - 2× MCP, 2× Repos, 1× News, 12× Generic Hype",
        "3. **Claude-Skills-Feature ist bei Indie-Devs der Hot-Topic** — Aria hat dieses System schon (skill-creator + 80+ installierte Skills) und ist damit im Vorteil. Die externen Skill-Empfehlungen sollten gegen `02-Wissen/integration-wishlist.md` cross-checked werden.",
        "",
        "## Empfohlene Deep-Watch-Kandidaten (für Kais)",
        "",
        "Wenn nur 2-3 Reels claude-watch wert sind:",
        "",
        "1. **DWZjz6xgBV1 — @bennyautomates — '4 GitHub-Repos mit zusammen 200k+ stars'** (2.1k likes)\n"
        "   Konkret-actionable Repo-Liste, Aria's integration-wishlist-Update-Kandidat.",
        "2. **DVRu6GlDNHO — @mikemeansbusiness_ai — '5 Repos für Claude Code'** (8.4k likes — höchstes-engagement Repo-Reel)\n"
        "   Zweite Repo-Liste, sollte mit oben gemerged werden.",
        "3. **DYQBqwToCau — @florent_preusser — 'Claude besorgt dir jetzt Backlinks (2 Prompts)'**\n"
        "   Das ist der einzige nicht-meta SEO/Business-Hack-Reel — falls Kadi-v2 SEO braucht, die 2 Prompts wert.",
        "",
        "Optional: **DYC831vgY8y — @bennyautomates — 'Graphify Knowledge-Graph reduziert Token-Verbrauch'** — Aria hat graphify schon, der Reel zeigt aber den use-case besser als unsere Doku.",
        "",
        "## Skip-Liste",
        "",
        "- **DYNOpkJjjZd** — Reel-Page liefert keine OG-Tags zurück (vermutlich gelöscht oder privat).",
        "- **DYUG44IsY_y, DYT7ZLDM-at** — explizit ausgenommen, anderer Subagent macht Frame-Analyse.",
        "- **Duplikate:** DYM5ckFoEje und DXUgRpECmHh erscheinen 2× in der Eingangsliste, wurden dedupliziert.",
        "",
        "## Anti-Patterns aus dem Mass-Audit",
        "",
        "- **Engagement-Bait dominant:** ~70% der Reels nutzen 'Comment X to get the link' statt direkter Wertvermittlung. Aria sollte das beim Aria-Distribution NICHT imitieren (substance-first).",
        "- **Re-Use derselben Skill-Empfehlungen** über mehrere Creators (Emil Kowalski Animation, Graphify, shadcn) → bestätigt: das sind echte breite Empfehlungen, nicht einzelne Affiliate-Calls.",
        "",
        "## Kosten-Bilanz",
        "",
        "- yt-dlp+Cookies-Run: ~8 reels OK + viele Rate-Limit-Versuche → abgebrochen.\n"
        "- OG-Scrape-Run: 44/45 in <30s, **Cost ~$0** (curl + python-regex, kein LLM-Aufruf).\n"
        "- Cluster + Notes-Generation: 100% deterministischer Code, **Cost $0**.\n"
        "- **Gesamt-Cost Phase 4 (Mass-Audit): praktisch $0** — der $5-Cap ist nicht ansatzweise erreicht.",
    ]
    out.write_text("\n".join(lines))
    return out


def main() -> int:
    data = json.loads(SRC.read_text())
    by_cluster = data["items_by_cluster"]
    labels = data["summary"]["cluster_labels"]
    total = data["summary"]["total_items"]
    # Skipped = 1 (DYNOpkJjjZd) — read from skip file directly
    skip_path = DIR / "_reels-skipped.txt"
    skipped_count = sum(1 for _ in skip_path.read_text().splitlines() if _.strip())

    written = []
    for cluster_key, items in sorted(by_cluster.items(), key=lambda kv: -len(kv[1])):
        if not items:
            continue
        label = labels.get(cluster_key, cluster_key)
        p = write_cluster_note(cluster_key, items, label)
        written.append(p)
        print(f"WROTE  {p.name}  ({len(items)} reels)")

    master = write_master(by_cluster, labels, total, skipped_count)
    written.append(master)
    print(f"WROTE  {master.name}  (master index)")

    return 0


if __name__ == "__main__":
    raise SystemExit(main())
