#!/usr/bin/env python3
"""Deep analysis for xmon 2026-11-04.

Sections:
  1. Buckets (handle-group first, is_ai flag) + disjoint sum check
  2. Raw core ranking + organic (like-rate >= 0.15%) ranking
  3. 24h deltas vs 2026-11-03 on shared tweet ids
  4. Per-handle freshness (max createdAt, in-window counts)
  5. Originals-only dormancy
  6. Offer / arbitrage grep over in-window originals
  7. Key chronologies
"""
import json, re, os
from datetime import datetime, timezone, timedelta

RAW = "/home/kiro/trend-engine/trends/x/raw"
TODAY, PREV = "2026-11-04", "2026-11-03"
d = json.load(open(f"{RAW}/scan_results_{TODAY}_FULL.json"))
p = json.load(open(f"{RAW}/scan_results_{PREV}_FULL.json"))

raw_all = d["raw"]
NOW = datetime.now(timezone.utc)
CUT = NOW.replace(hour=0, minute=0, second=0, microsecond=0) - timedelta(days=3)

IRRELEVANT = {"AIBuzzNews","AIGuideHQ","AITECHio","AIFrontliner","TheAIColony","AITOPIAai",
 "GoogleLabs","GoogleAI","DonutAI","cladlabs","FaithJaiye2187","KammelaBala","MyStageAI",
 "AlexStudio44","AI_with_jasmin","Ai_Vaidehi","ChrisLaubAI","CINEMA505","OpenAI","AnthropicAI",
 "AIScottAdams","AISuperDomain","AI_Jasonyu","AIByLeo","Soaima_Ai","different_ai","via_ai_",
 "Teamily_AI","AIsaOneHQ","AiWithTariq","numerai"}
FILM = {"DiscussingFilm","nofilmschool"}
NON_CORE = {"interesting_aIl","hubermanlab","NVIDIAAI"}

def pd(s):
    try: return datetime.strptime(s, "%a %b %d %H:%M:%S %z %Y")
    except Exception: return None

def score(t):
    return ((t.get("likeCount") or 0) + 2*(t.get("retweetCount") or 0)
            + 3*(t.get("replyCount") or 0) + (t.get("viewCount") or 0)/100)

def qual(t):
    return ((t.get("likeCount") or 0) >= 50 or (t.get("retweetCount") or 0) >= 10
            or (t.get("viewCount") or 0) >= 1000)

def is_orig(t):
    return not (t.get("retweeted_tweet") or t.get("type") == "retweet"
                or (t.get("text") or "").startswith("RT @"))

def mediatype(t):
    m = t.get("media")
    if isinstance(m, list) and m: return m[0].get("type", "?")
    return "-"

# NOTE: leading AND trailing \b are both required. A leading-only \b matched
# "ai" inside "aired" (re.I) and produced a FALSE AI-relevant positive in the
# film bucket on 2026-11-04. Fixed here.
STRONG = re.compile(r"\b(AI|A\.I\.|artificial intelligence|generative|LLM|GPT|diffusion|"
                    r"machine learning|neural|prompts?|models? generat\w*)\b", re.I)

# ---------- 1. BUCKETS ----------
buckets = {"core":[], "film":[], "irrelevant":[], "labs":[], "offtopic":[], "health":[], "new":[]}
rows = []
for h, tw in raw_all.items():
    for t in tw:
        dt = pd(t.get("createdAt",""))
        if not dt or dt < CUT or not is_orig(t) or not qual(t): continue
        if h in ("OpenAI","AnthropicAI","NVIDIAAI"): g = "labs"
        elif h == "interesting_aIl": g = "offtopic"
        elif h == "hubermanlab": g = "health"
        elif h in FILM: g = "film"
        elif h in IRRELEVANT: g = "irrelevant"
        else: g = "core"
        r = {"h":h,"g":g,"dt":dt,"score":score(t),"likes":t.get("likeCount") or 0,
             "rt":t.get("retweetCount") or 0,"replies":t.get("replyCount") or 0,
             "views":t.get("viewCount") or 0,"text":(t.get("text") or "").replace("\n"," ").strip(),
             "url":f"https://x.com/{h}/status/{t.get('id')}","id":str(t.get("id")),
             "media":mediatype(t),
             "is_ai":bool(STRONG.search((t.get("text") or ""))),
             "quoted":bool(t.get("quoted_tweet"))}
        buckets[g].append(r); rows.append(r)

print("===== 1. BUCKETS (disjoint) =====")
tot = 0
for g,v in buckets.items():
    ai = sum(1 for x in v if x["is_ai"])
    print(f"  {g:12s} {len(v):4d}   AI-relevant: {ai}")
    tot += len(v)
print(f"  SUM {tot}  vs qualifying {len(d['qualifying'])}  ->",
      "OK" if tot == len(d["qualifying"]) else "MISMATCH")

# ---------- 2. RANKINGS ----------
core = buckets["core"]
raw_rank = sorted(core, key=lambda x: -x["score"])
for x in raw_rank:
    x["lr"] = (x["likes"]/x["views"]*100) if x["views"] else 0
org = sorted([x for x in core if x["lr"] >= 0.15], key=lambda x: -x["score"])

print("\n===== 2a. CORE RAW TOP 12 (score) =====")
for i,x in enumerate(raw_rank[:12],1):
    print(f"{i:2d}|@{x['h']}|{x['likes']}L|{x['rt']}RT|{x['replies']}R|{x['views']}V|"
          f"lr={x['lr']:.2f}%|{x['dt'].strftime('%m-%d %H:%M')}|scr={x['score']:.0f}|{x['media']}|{x['text'][:110]}")

print("\n===== 2b. CORE ORGANIC TOP 12 (like rate >= 0.15%) =====")
for i,x in enumerate(org[:12],1):
    print(f"{i:2d}|@{x['h']}|{x['likes']}L|{x['rt']}RT|{x['replies']}R|{x['views']}V|"
          f"lr={x['lr']:.2f}%|{x['dt'].strftime('%m-%d %H:%M')}|scr={x['score']:.0f}|{x['text'][:110]}")
if len(org) > 12:
    print(f"  cutoff scr={org[9]['score']:.0f}  rank11 scr={org[10]['score']:.0f}")

print("\n===== 2c. PAID-REACH WATCH (view-heavy, like rate < 0.15%) =====")
for x in raw_rank[:14]:
    if x["lr"] < 0.15:
        print(f"   @{x['h']}|{x['likes']}L|{x['views']}V|lr={x['lr']:.3f}%|{x['text'][:80]}")

# ---------- 3. 24H DELTAS ----------
def idmap(js):
    m = {}
    for h, tw in js["raw"].items():
        for t in tw:
            if is_orig(t) and t.get("id"):
                m[str(t["id"])] = (h, t)
    return m
cur, prv = idmap(d), idmap(p)
shared = set(cur) & set(prv)
deltas = []
for i in shared:
    h,tc = cur[i]; _,tp = prv[i]
    dl = (tc.get("likeCount") or 0) - (tp.get("likeCount") or 0)
    dv = (tc.get("viewCount") or 0) - (tp.get("viewCount") or 0)
    if dv or dl:
        deltas.append((dl, dv, h, tc, i))
print(f"\n===== 3. 24H DELTAS ({len(shared)} shared ids, {len(deltas)} changed) =====")
for dl,dv,h,t,i in sorted(deltas, key=lambda z:-z[1])[:15]:
    print(f"  @{h}|L{dl:+d}|V{dv:+d}|now {t.get('likeCount')}L/{t.get('viewCount')}V|{t.get('text','')[:80]}")
print("  -- biggest LIKE gains --")
for dl,dv,h,t,i in sorted(deltas, key=lambda z:-z[0])[:8]:
    if dl > 0: print(f"  @{h}|L{dl:+d}|V{dv:+d}|{t.get('text','')[:80]}")
print("  -- NEGATIVE like deltas --", sum(1 for z in deltas if z[0] < 0))
for dl,dv,h,t,i in sorted(deltas, key=lambda z:z[0])[:5]:
    if dl < 0: print(f"  @{h}|L{dl:+d}|V{dv:+d}|{t.get('text','')[:80]}")

# ---------- 4. FRESHNESS ----------
print("\n===== 4. FRESHNESS =====")
fr = []
for h, tw in raw_all.items():
    dts = [pd(t.get("createdAt","")) for t in tw]
    dts = [x for x in dts if x]
    if not dts: continue
    mx = max(dts); hrs = (NOW-mx).total_seconds()/3600
    inw = sum(1 for t in tw if (pd(t.get("createdAt","")) or CUT-timedelta(days=1)) >= CUT and is_orig(t))
    fr.append((hrs, h, mx, inw, len(tw)))
fr.sort()
print("  freshest:")
for hrs,h,mx,inw,n in fr[:12]:
    print(f"   @{h} {hrs:6.1f}h n={n} inwin={inw}")
print("  key accounts:")
for hrs,h,mx,inw,n in fr:
    if h in ("NVIDIAAI","venturetwins","EHuanglu","pika_labs","Kling_ai","runwayml","higgsfield",
             "higgsfield_ai","Flovaai","AIWarper","CharaspowerAI","c_valenzuelab","azed_ai",
             "heyglif","ElsaSofia__AI","ItsMaryamAi","AI__TSUBAKI","openart_ai"):
        print(f"   @{h} {hrs:6.1f}h n={n} inwin={inw}")
print("  stalest:")
for hrs,h,mx,inw,n in fr[-10:]:
    print(f"   @{h} {hrs:6.1f}h n={n} inwin={inw}")

# ---------- 5. DORMANCY ----------
print("\n===== 5. DORMANCY (originals only) =====")
watch = ["CuriousRefuge","karenxcheng","higgsfield","higgsfield_ai","WuxiaRocks","EinsiaAI",
         "pika_labs","AI__TSUBAKI","AIsaOneHQ","AIGuideHQ","AITOPIAai"]
for h in watch:
    tw = raw_all.get(h, [])
    origs = [pd(t.get("createdAt","")) for t in tw if is_orig(t)]
    origs = [x for x in origs if x]
    if not origs:
        print(f"   @{h}: NO originals in fetched set (n={len(tw)})"); continue
    mx = max(origs); hrs = (NOW-mx).total_seconds()/3600
    inw = [x for x in origs if x >= CUT]
    best = 0
    for t in tw:
        dt = pd(t.get("createdAt",""))
        if dt and dt >= CUT and is_orig(t):
            best = max(best, t.get("likeCount") or 0)
    verdict = "DORMANT" if not inw else f"ARTEFACT (best {best}L)"
    print(f"   @{h}: newest orig {mx.strftime('%Y-%m-%d %H:%M')} ({hrs:.1f}h) inwin={len(inw)} -> {verdict}")

# ---------- 6. OFFERS ----------
print("\n===== 6. OFFER / ARBITRAGE GREP =====")
PATS = {
 "Flova launch special": r"(2 years of Pro|Buy 1 Year|price of 1|Launch Special)",
 "Flova credits/giveaway": r"(1,000 credits|credits each|Follow\+Repost|giveaway|winners)",
 "Pika H3": r"(H3 Flex|pika\.art|\$0\.01)",
 "Higgsfield offer": r"(unlimited|Genjutsu|Content Factory|Ads Studio|cashback)",
 "CapCut": r"(CapCut|capcutapp)",
 "DaVinci": r"(DaVinci|Resolve)",
 "Topaz": r"(Topaz|Starlight)",
 "Topview": r"(Topview|Topviewai)",
 "Chroma Awards": r"(Chroma|chromaawards)",
 "OpenArt": r"(openart|OpenArt)",
 "Seedance price": r"(\$0\.0[0-9]+|per second|/sec)",
 "Kling 4 / PixVerse": r"(Kling 4|PixVerse|Kling 4\.0)",
 "Runway dev": r"(dev\.runway|Runway API|Cursor)",
 "free credits/trial": r"(free generations|free credits|free trial|no credit|zero credit)",
 "discount/promo": r"(\d+% off|promo code|discount|coupon)",
 "Nebius": r"(Nebius|AI Studio|AI Builder)",
 "Magnific": r"(Magnific|Move app|Brand Kit)",
 "Dreamina": r"(Dreamina|DreaminaCPP)",
 "Seedream/Nano Banana": r"(Seedream|Nano Banana)",
 "Glif": r"(glif|Glif)",
 "HeyGen/avatar": r"(HeyGen|avatar|presenter)",
}
inw_all = [x for x in rows]
for label, pat in PATS.items():
    rx = re.compile(pat, re.I)
    hits = [x for x in inw_all if rx.search(x["text"])]
    if not hits:
        print(f"  [{label}] 0 hits")
        continue
    print(f"  [{label}] {len(hits)} hits")
    for x in sorted(hits, key=lambda z:-z["score"])[:4]:
        print(f"     @{x['h']}|{x['likes']}L|{x['views']}V|{x['dt'].strftime('%m-%d %H:%M')}|{x['text'][:170]}")

# ---------- 7. CHRONOLOGIES ----------
print("\n===== 7. CHRONOLOGIES =====")
for h in ["EHuanglu","heyglif","Flovaai","CharaspowerAI","azed_ai","pika_labs","runwayml","Kling_ai","AIWarper"]:
    tw = raw_all.get(h, [])
    sel = []
    for t in tw:
        dt = pd(t.get("createdAt",""))
        if not dt or dt < CUT or not is_orig(t): continue
        sel.append((dt, t))
    if not sel: 
        print(f"\n  @{h}: none in window"); continue
    print(f"\n  @{h} ({len(sel)} in-window originals):")
    for dt,t in sorted(sel, key=lambda z: z[0], reverse=True):
        print(f"    {dt.strftime('%m-%d %H:%M')}|{t.get('likeCount') or 0}L|{t.get('viewCount') or 0}V|{mediatype(t)}|{(t.get('text') or '')[:150]}")
