#!/usr/bin/env python3
"""Dormancy check (RT-filtered) + promo grep for the X monitor run.

Reads scan_results_<date>_FULL.json.
  raw[handle][]      -> userName, likeCount, retweetCount, viewCount, createdAt, text
  qualifying[]       -> handle, score, date, likes, rt, replies, views, text, url
Mixing the two shapes yields all-None output with no error -- see 2026-10-11 note.
RT check MUST run against raw[handle][], never against qualifying.
"""
import json, re, sys
from datetime import datetime, timezone, timedelta, timedelta

date = sys.argv[1]
p = f"/home/kiro/trend-engine/trends/x/raw/scan_results_{date}_FULL.json"
d = json.load(open(p))
q = d["qualifying"]
raw = d["raw"]
handles = d["handles"]

now = datetime.now(timezone.utc)
cutoff = now.replace(hour=0, minute=0, second=0, microsecond=0) - timedelta(days=3)

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

def is_original(t):
    if t.get("retweeted_tweet"):
        return False
    if (t.get("text") or "").startswith("RT @"):
        return False
    return True

active = {x["handle"] for x in q}
# also count handles that fetched but had zero qualifying
print(f"=== DORMANCY CHECK {date} (cutoff {cutoff.isoformat()}) ===")
print(f"handles scanned: {len(handles)} | with >=1 qualifier: {len(active)}")

zero = [h for h in handles if h not in active]
print(f"zero-qualifying handles: {len(zero)}")

for h in zero:
    tw = raw.get(h) or []
    newest = max((pdate(t.get("createdAt","")) for t in tw if pdate(t.get("createdAt",""))), default=None)
    orig = [t for t in tw if is_original(t)]
    newest_orig = max((pdate(t.get("createdAt","")) for t in orig if pdate(t.get("createdAt",""))), default=None)
    inwin = [t for t in orig if (pdate(t.get("createdAt","")) or cutoff) >= cutoff]
    def fmt(dt):
        if not dt: return "NEVER/none"
        return f"{dt.strftime('%Y-%m-%d')} ({(now-dt).days}d)"
    flags = []
    if inwin:
        best = max(inwin, key=lambda t: (t.get("likeCount") or 0) + (t.get("viewCount") or 0)/100)
        flags.append(f"IN-WINDOW ORIGINALS={len(inwin)} best={best.get('likeCount')}L/{best.get('viewCount')}V")
    if newest_orig is None or newest_orig < cutoff:
        flags.append("OUT-OF-WINDOW")
    rts_only = (not orig) and tw
    if rts_only:
        flags.append("RT-ONLY FEED")
    print(f"@{h}: newest_fetched={fmt(newest)} newest_ORIGINAL={fmt(newest_orig)} | " + "; ".join(flags))

# RT-artefact check: handles whose in-window raw posts are all retweets
print("\n=== RT-ONLY IN-WINDOW (zero scoreable posts) ===")
for h in handles:
    tw = raw.get(h) or []
    inwin = [t for t in tw if (pdate(t.get("createdAt","")) or cutoff) >= cutoff]
    if inwin and not any(is_original(t) for t in inwin) and h not in active:
        print(f"@{h}: {len(inwin)} in-window tweets, all retweets")

# core top-10 cutoff
core = [x for x in q if x["handle"] not in {"DiscussingFilm","nofilmschool","OpenAI","AnthropicAI"}
        and x["handle"] not in {"AIBuzzNews","AIGuideHQ","AITECHio","AIFrontliner","TheAIColony","AITOPIAai",
        "GoogleLabs","GoogleAI","DonutAI","cladlabs","FaithJaiye2187","KammelaBala","MyStageAI",
        "AlexStudio44","AI_with_jasmin","Ai_Vaidehi","ChrisLaubAI","CINEMA505","AIScottAdams",
        "AISuperDomain","AI_Jasonyu","AIByLeo"}]
core.sort(key=lambda x: x["score"], reverse=True)
print(f"\n=== CORE CUTOFF === qualifying {len(core)}")
if len(core) >= 11:
    print(f"rank10 score {core[9]['score']:.0f} (@{core[9]['handle']}) | rank11 score {core[10]['score']:.0f} (@{core[10]['handle']})")

# promo grep
TERMS = ["cashback","free credit","credits","unlimited","% off","discount","referral","promo",
         "free trials","free tier","free gener","coupon","code ","voucher","giveaway","grant",
         "Magnific","Dreamina","Dolphin","Flova","Air ","Higgsfield","Katana","Seedance","affiliate",
         "waitlist","early access","open source","open-sourc","github.com"]
print("\n=== PROMO / CREDIT GREP (qualifying text) ===")
for term in TERMS:
    hits = [x for x in q if term.lower() in x["text"].lower()]
    if hits:
        print(f"\n-- {term} ({len(hits)}) --")
        for x in sorted(hits, key=lambda z: z["score"], reverse=True)[:6]:
            print(f"  @{x['handle']} {x['likes']}L/{x['views']}V {x['date']} :: {x['text'][:180]}")
            print(f"    {x['url']}")
