#!/usr/bin/env python3
"""Deep analysis for 2026-11-05 x-account-monitor run.

Buckets assigned by HANDLE GROUP first (never AI-filtered inside the loop),
disjoint-sum verified. Prints raw + organic core rankings with like rates,
24h deltas vs 11-04, per-handle freshness, originals-only dormancy,
offer/pricing grep over in-window originals, and new-handle checks.
"""
import json, os, re
from datetime import datetime, timedelta, timezone

RAW = "/home/kiro/trend-engine/trends/x/raw"
D = "2026-11-05"
P = "2026-11-04"

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"}
NON_CORE = {"interesting_aIl","hubermanlab","NVIDIAAI"}
FILM = {"DiscussingFilm","nofilmschool"}
CORE = ["runwayml","CuriousRefuge","nofilmschool","venturetwins","Kling_ai","paultrillo",
 "c_valenzuelab","karenxcheng","higgsfield","pika_labs","EHuanglu","azed_ai","JeffSynthesized",
 "ai_filmmaker","Magiermogul","WuxiaRocks","JiamingSuen","higgsfield_ai","Chandan_Perla",
 "CharaspowerAI","AIWarper","ItsMaryamAi","ElsaSofia__AI","AI__TSUBAKI","heyglif"]
CORESET = set(CORE)

STRONG = re.compile(r"\b(AI|A\.I\.|artificial intelligence|generative|text-to-video|image-to-video|"
                    r"Seedance|Midjourney|Sora|Veo|Kling|Runway|Pika|Higgsfield|ComfyUI|diffusion|"
                    r"machine learning|prompt|ChatGPT|GPT|LLM|agentic|model)\b", re.I)

def load(date):
    return json.load(open(os.path.join(RAW, f"scan_results_{date}_FULL.json")))

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

def score(q):
    return q["likes"] + 2*q["rt"] + 3*q["replies"] + q["views"]/100

def likerate(q):
    return (q["likes"]/q["views"]*100) if q["views"] else 0.0

def tid(url):
    m = re.search(r"/status/(\d+)", url or "")
    return m.group(1) if m else None

cur = load(D); prev = load(P)
q = cur["qualifying"]
now = datetime.now(timezone.utc)

print(f"=== RUN {D} ===  handles={len(cur['handles'])} fetched={len(cur['raw'])} "
      f"failures={len(cur['failures'])} qualifying={len(q)}")
print(f"prev {P}: qualifying={len(prev['qualifying'])} -> delta {len(q)-len(prev['qualifying']):+d}")

# ---- watchlist diff ----
wl_txt = open("/home/kiro/trend-engine/trends/x/raw/rising-accounts.md").read()
wl = sorted({h for h in re.findall(r"@(\w+)", wl_txt)})
print(f"watchlist md handles={len(wl)}  scan handles={len(cur['handles'])}")

# ---- disjoint buckets by handle group ----
buckets = {"core":[], "film":[], "irrelevant":[], "labs":[], "offtopic":[], "health":[]}
for x in q:
    h = x["handle"]
    if h == "NVIDIAAI" or h in ("OpenAI","AnthropicAI"): buckets["labs"].append(x)
    elif h == "interesting_aIl": buckets["offtopic"].append(x)
    elif h == "hubermanlab": buckets["health"].append(x)
    elif h in FILM: buckets["film"].append(x)
    elif h in IRRELEVANT: buckets["irrelevant"].append(x)
    else: buckets["core"].append(x)

tot = sum(len(v) for v in buckets.values())
print("\n=== BUCKETS ===")
for k,v in buckets.items():
    print(f"  {k:11s} {len(v):4d}")
print(f"  {'ASSIGNED':11s} {tot:4d}  vs qualifying {len(q)}  -> "
      f"{'OK' if tot==len(q) else 'MISMATCH'}")

film_ai = [x for x in buckets["film"] if STRONG.search(x["text"])]
irr_ai  = [x for x in buckets["irrelevant"] if STRONG.search(x["text"])]
print(f"  film AI-relevant: {len(film_ai)} of {len(buckets['film'])}")
print(f"  irrelevant AI-relevant: {len(irr_ai)} of {len(buckets['irrelevant'])}")

# ---- core rankings ----
core = sorted(buckets["core"], key=score, reverse=True)
print(f"\n=== CORE TOP 20 (raw score) of {len(core)} ===")
for i,x in enumerate(core[:20],1):
    print(f"{i:2d}|@{x['handle']:16s}|{x['likes']:6d}L|{x['rt']:5d}RT|{x['replies']:4d}R|"
          f"{x['views']:9d}V|{likerate(x):5.2f}%|{x['date']}|{x['url']}")
cut10 = score(core[9]) if len(core)>=10 else 0
cut11 = score(core[10]) if len(core)>10 else 0
print(f"raw core top-10 cutoff: {cut10:.0f} / rank 11: {cut11:.0f}")

org = [x for x in core if likerate(x) >= 0.15]
org.sort(key=score, reverse=True)
print(f"\n=== CORE TOP 12 ORGANIC (like rate >= 0.15%) of {len(org)} ===")
for i,x in enumerate(org[:12],1):
    print(f"{i:2d}|@{x['handle']:16s}|{x['likes']:6d}L|{x['views']:9d}V|{likerate(x):5.2f}%|"
          f"{x['date']}|{x['url']}")
paid = [x for x in core if likerate(x) < 0.15 and x["views"] >= 100000]
print(f"paid-reach core posts (>=100k views, <0.15% like rate): {len(paid)}")
for x in paid:
    print(f"   @{x['handle']} {x['likes']}L/{x['views']}V {likerate(x):.3f}% {x['date']}")

# ---- 24h deltas ----
prevm = {}
for x in prev["qualifying"]:
    i = tid(x["url"])
    if i: prevm[i] = x
print("\n=== 24H DELTAS (core, present both days) ===")
rows=[]
for x in core:
    i=tid(x["url"]); p=prevm.get(i)
    if not p: continue
    rows.append((x["likes"]-p["likes"], x["views"]-p["views"], x))
rows.sort(key=lambda r: r[0], reverse=True)
for dl,dv,x in rows[:14]:
    print(f"  +{dl:5d}L +{dv:8d}V  @{x['handle']:15s} now {x['likes']}L/{x['views']}V "
          f"{likerate(x):.2f}%  {x['date']}")
print("  --- negative / flat ---")
for dl,dv,x in rows:
    if dl<=5:
        print(f"  {dl:+6d}L {dv:+9d}V  @{x['handle']:15s} now {x['likes']}L/{x['views']}V "
              f"{likerate(x):.3f}%")

# ---- freshness ----
print("\n=== FRESHNESS (hours since newest fetched tweet) ===")
fr=[]
for h,tw in cur["raw"].items():
    ds=[pdate(t.get("createdAt","")) for t in tw]
    ds=[d for d in ds if d]
    if ds: fr.append(((now-max(ds)).total_seconds()/3600, h, len(ds)))
fr.sort()
print("  freshest:", ", ".join(f"@{h} {a:.1f}h" for a,h,n in fr[:12]))
print("  stalest: ", ", ".join(f"@{h} {a:.0f}h" for a,h,n in fr[-12:]))
print("  key accounts:")
for a,h,n in fr:
    if h in {"higgsfield","higgsfield_ai","runwayml","Kling_ai","pika_labs","EHuanglu","Flovaai",
             "azed_ai","CharaspowerAI","heyglif","c_valenzuelab","venturetwins","openart_ai",
             "AIWarper","ItsMaryamAi","ElsaSofia__AI","NVIDIAAI","CuriousRefuge"}:
        print(f"    @{h:16s} n={n:2d} newest {a:6.1f}h ago")

# ---- dormancy: originals only, in-window ----
cutoff = now.replace(hour=0,minute=0,second=0,microsecond=0) - timedelta(days=3)
print("\n=== DORMANCY (originals only) ===")
for h in ["CuriousRefuge","karenxcheng","higgsfield","higgsfield_ai","WuxiaRocks","AI__TSUBAKI",
          "EinsiaAI","azed_ai","ItsMaryamAi","openart_ai","CuriousRefuge"]:
    tw = cur["raw"].get(h) or []
    orig=[(pdate(t.get("createdAt","")),t) for t in tw
          if not t.get("retweeted_tweet") and t.get("type")!="retweet"
          and not (t.get("text") or "").startswith("RT @")]
    orig=[(d,t) for d,t in orig if d]
    if not orig:
        print(f"  @{h:16s} NO ORIGINALS IN FETCHED SET"); continue
    newest=max(d for d,_ in orig)
    inw=[t for d,t in orig if d>=cutoff]
    best=max((t.get('likeCount') or 0) for t in inw) if inw else 0
    print(f"  @{h:16s} newest {(now-newest).total_seconds()/3600:8.1f}h  originals={len(orig):2d}"
          f"  in-window={len(inw):2d}  best_likes={best:5d}"
          f"{'  <-- DORMANT' if newest<cutoff else ''}")

# ---- offer / pricing grep over in-window originals ----
PATS = [r"\bfree\b", r"giveaway", r"contest", r"competition", r"\bcredit", r"\bpromo\b",
        r"code\s+[A-Z0-9]{4,}", r"discount", r"\boff\b", r"%\s*off", r"\$\d", r"\d+\s*/\s*sec",
        r"per second", r"unlimited", r"new users", r"expires", r"ends\b", r"until\b", r"deadline",
        r"apply by", r"\bprize", r"\$[0-9,.]+[KM]?", r"launch special", r"\btrial\b", r"open weights",
        r"open source", r"waitlist", r"early access", r"beta\b", r"award", r"\bwin\b", r"winner"]
rx = re.compile("|".join(PATS), re.I)
print("\n=== OFFER / PRICING GREP (in-window originals) ===")
n_orig=0
for h,tw in cur["raw"].items():
    for t in tw:
        if t.get("retweeted_tweet") or t.get("type")=="retweet": continue
        txt=(t.get("text") or "")
        if txt.startswith("RT @"): continue
        d=pdate(t.get("createdAt",""))
        if not d or d<cutoff: continue
        n_orig+=1
        if rx.search(txt):
            hits=set(m.group(0).lower() for m in rx.finditer(txt))
            print(f"  @{h:15s} {(t.get('likeCount') or 0):5d}L/{(t.get('viewCount') or 0):8d}V "
                  f"{d.strftime('%m-%d %H:%M')} {sorted(hits)[:5]}")
            print(f"      {txt.replace(chr(10),' ')[:260]}")
print(f"  ({n_orig} in-window originals scanned)")

# ---- new / unclassified handles in top ranks ----
print("\n=== UNCLASSIFIED HANDLE CHECK ===")
known = CORESET | IRRELEVANT | NON_CORE | FILM
seen=set()
for i,x in enumerate(core[:25],1):
    if x["handle"] not in known and x["handle"] not in seen:
        seen.add(x["handle"])
        print(f"  core #{i} @{x['handle']} NOT in any set: {x['likes']}L/{x['views']}V "
              f"{likerate(x):.2f}% {x['url']}")
        print(f"      {x['text'][:220]}")

# ---- per-bucket spotlights ----
print("\n=== FILM BUCKET (AI matches) ===")
for x in sorted(film_ai, key=score, reverse=True):
    print(f"  @{x['handle']} {x['likes']}L/{x['views']}V {x['date']}: {x['text'][:200]}")
print("  (empty = correct output)")

print("\n=== FILM BUCKET top 5 raw (correctly excluded) ===")
for x in sorted(buckets["film"], key=score, reverse=True)[:5]:
    print(f"  @{x['handle']} {x['likes']}L/{x['views']}V {x['date']}: {x['text'][:120]}")

print("\n=== IRRELEVANT AI-RELEVANT ===")
for x in sorted(irr_ai, key=score, reverse=True)[:12]:
    print(f"  @{x['handle']} {x['likes']}L/{x['views']}V {likerate(x):.2f}% {x['date']}: {x['text'][:150]}")

print("\n=== LABS ===")
for x in sorted(buckets["labs"], key=score, reverse=True)[:12]:
    print(f"  @{x['handle']} {x['likes']}L/{x['views']}V {x['date']}: {x['text'][:150]}")
