#!/usr/bin/env python3
"""X Account Monitor scan + score for 2026-09-10 (requests-based, skill-compliant)."""
import os, re, json, time, sys
import requests
from datetime import datetime, timezone, timedelta

env_path = os.path.expanduser("~/.hermes/.env")
API_KEY = None
with open(env_path) as f:
    for line in f:
        if line.startswith("GETXAPI_KEY="):
            API_KEY = line.strip().split("=", 1)[1]
            break
if not API_KEY:
    print("ERROR: no GETXAPI_KEY", file=sys.stderr); sys.exit(1)

WATCHLIST = "/home/kiro/trend-engine/trends/x/raw/rising-accounts.md"
with open(WATCHLIST) as f:
    content = f.read()
raw_handles = re.findall(r"@(\w+)", content)

SKIP_WORDS = {'x','youtube','facebook','marketingbrew','besttwitteraccounts',
              'theankler','xo2','etcjournal','letsdatascience','pixflow',
              'blogs','nvidia'}

CORE = [
    "runwayml","CuriousRefuge","nofilmschool","venturetwins","Kling_ai",
    "paultrillo","c_valenzuelab","CorridorDigital","karenxcheng","higgsfield",
    "pika_labs","EHuanglu","azed_ai","JeffSynthesized","ai_filmmaker",
    "visiblemaker","Magiermogul","WuxiaRocks","JiamingSuen","moonvalley",
    "higgsfield_ai","Chandan_Perla",
]

IRRELEVANT = [
    "AITOPIAai","FaithJaiye2187","KammelaBala","MyStageAI",
    "AI_Video_Dumps","ChrisLaubAI","GoogleLabs","TheAIColony","cladlabs",
    "AIBuzzNews","AlexStudio44","DonutAI","GoogleAI",
    "AI_with_jasmin","CharaspowerAI","Ai_Vaidehi","CINEMA505",
    "AIFrontliner","AIGuideHQ","AIWarper","AITECHio","4aibsc",
]

core_set = set(CORE)
irrelevant_set = set(IRRELEVANT)

handles = []
seen = set()
for h in CORE + IRRELEVANT:
    if h not in seen:
        handles.append(h); seen.add(h)
for h in raw_handles:
    if h in SKIP_WORDS or h in seen:
        continue
    handles.append(h); seen.add(h)

print("HANDLES TO SCAN (%d):" % len(handles))
print(", ".join(handles))
print("---", flush=True)

DATE_FMT = "%a %b %d %H:%M:%S %z %Y"
TODAY = datetime.now(timezone.utc).strftime("%Y-%m-%d")
OUT = "/home/kiro/trend-engine/trends/x/scan_results_%s_FULL.json" % TODAY

all_results = {}
failed = []
for handle in handles:
    url = "https://api.getxapi.com/twitter/user/tweets?userName=%s&count=5" % handle
    ok = False
    err = "unknown"
    for attempt, delay in enumerate([0, 3, 6]):
        try:
            resp = requests.get(url, headers={"Authorization": "Bearer %s" % API_KEY}, timeout=60)
            if resp.status_code != 200:
                err = "HTTP %d" % resp.status_code
                time.sleep(delay); continue
            data = resp.json()
            tweets = data.get("tweets", []) if isinstance(data, dict) else []
            all_results[handle] = tweets
            ok = True
            print("OK %s: %d tweets" % (handle, len(tweets)), flush=True)
            break
        except Exception as e:
            err = str(e)
            time.sleep(delay)
    if not ok:
        failed.append((handle, err))
        print("FAIL %s: %s" % (handle, err), flush=True)
    time.sleep(0.8)

with open(OUT, "w") as f:
    json.dump({"results": all_results, "failed": [x[0] for x in failed]}, f)
print("---\nSaved %s" % OUT)

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

def parse_date(s):
    try:
        return datetime.strptime(s, DATE_FMT)
    except Exception:
        return None

qualifying = []
filtered_qualifying = []
for handle, tweets in all_results.items():
    is_core = handle in core_set
    for tw in tweets:
        if not isinstance(tw, dict):
            continue
        if tw.get("retweeted_tweet") or tw.get("type") == "retweet":
            continue
        if (tw.get("text") or "").startswith("RT @"):
            continue
        likes = tw.get("likeCount") or 0
        rts = tw.get("retweetCount") or 0
        replies = tw.get("replyCount") or 0
        views = tw.get("viewCount") or 0
        dt = parse_date(tw.get("createdAt") or "")
        if dt is None or dt < cutoff:
            continue
        if not (likes >= 50 or rts >= 10 or views >= 1000):
            continue
        entry = {"handle": handle, "tweet": tw, "id": tw.get("id"),
                 "score": likes + rts * 2 + replies * 3 + views / 100,
                 "likes": likes, "rts": rts, "replies": replies, "views": views,
                 "date": dt.strftime("%Y-%m-%d")}
        (qualifying if is_core else filtered_qualifying).append(entry)

qualifying.sort(key=lambda x: -x["score"])
filtered_qualifying.sort(key=lambda x: -x["score"])

json.dump({"core": qualifying, "filtered": filtered_qualifying, "failed": [x[0] for x in failed]},
          open("/home/kiro/trend-engine/trends/x/scan_scored_%s.json" % TODAY, "w"))

print("\nCore qualifying: %d | Filtered qualifying: %d | Failures: %d"
      % (len(qualifying), len(filtered_qualifying), len(failed)))
print("CUTOFF:", cutoff.isoformat())
for e in qualifying[:15]:
    print("  %.0f  @%s  %s  %sL %sRT %sV" % (e["score"], e["handle"], e["date"], e["likes"], e["rts"], e["views"]))
inactive = [h for h in CORE if not any(e["handle"] == h for e in qualifying)]
print("INACTIVE (core, no qualifying 3d):", ", ".join("@" + h for h in inactive))
