#!/usr/bin/env python3
"""
X Account Monitor — Scan all watchlist accounts via GetXAPI
Saves high-engagement tweets (last 3 days) to JSON for report generation.
"""
import urllib.request
import json
import time
import sys
import os
from datetime import datetime, timezone, timedelta

API_KEY = "get-x-api-6157f8edb420c3d5e50e062287389aa55635cd7c9630c81f"
BASE_URL = "https://api.getxapi.com"
CUTOFF = datetime.now(timezone.utc) - timedelta(days=3)

HANDLES = [
    # AI/Film — Existing
    "runwayml", "Kling_ai", "pika_labs", "higgsfield", "Seedance",
    "nofilmschool", "CuriousRefuge", "DiscussingFilm",
    "venturetwins", "EHuanglu", "karenxcheng",
    "azed_ai", "JeffSynthesized", "paultrillo", "CorridorDigital", "visiblemaker",
    "NotionHQ", "zapier", "Linear", "a16z",
    "ai_filmmaker", "Magiermogul", "WuxiaRocks", "JiamingSuen", "moonvalley",
    "higgsfield_ai", "Chandan_Perla",
    "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",
    "c_valenzuelab",
    # NestraSleep — sleep/recovery
    "hubermanlab", "mattwalkersleep", "sleepfoundation", "eightsleep", "Oura",
    "Whoop", "drmarkhyman", "SleepDoctor", "drjenniferkushner",
    # OneHopSim — travel/eSIM
    "RickSteves", "LonelyPlanet", "nomadicmatt", "FodorsTravel", "Airalo",
    "Holafly", "Nomad_eSIM", "TurkishCulture", "VisitTurkey",
    # AI Info Business — cost-arbitrage
    "anthropicai", "OpenAI", "AndrewYNg", "kaishengtai",
]

def parse_date(created_at):
    if not created_at:
        return None
    try:
        dt = datetime.strptime(created_at, "%a %b %d %H:%M:%S %z %Y")
        return dt
    except:
        return None

def fetch_tweets(handle):
    url = f"{BASE_URL}/twitter/user/tweets?userName={handle}&count=5"
    req = urllib.request.Request(url, headers={"Authorization": f"Bearer {API_KEY}"})
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            body = resp.read().decode("utf-8", errors="replace")
        data = json.loads(body, strict=False)
        tweets = data.get("tweets", data)
        if isinstance(tweets, dict):
            tweets = [tweets]
        if not isinstance(tweets, list):
            return [], "unexpected response format"
        return tweets, None
    except urllib.error.HTTPError as e:
        err_body = e.read().decode("utf-8", errors="replace")
        return [], f"HTTP {e.code}: {err_body[:200]}"
    except Exception as e:
        return [], str(e)[:200]

def get_tweet_metrics(tweet):
    """Extract metrics from tweet response, handling different response shapes."""
    likes = tweet.get("likeCount", 0) or 0
    retweets = tweet.get("retweetCount", 0) or 0
    replies = tweet.get("replyCount", 0) or 0
    views = tweet.get("viewCount", 0) or 0
    bookmarks = tweet.get("bookmarkCount", 0) or 0
    
    # Get author info
    author = tweet.get("author", {}) or {}
    author_handle = author.get("userName", "")
    author_followers = author.get("followers", 0) or 0
    
    # Get tweet text
    text = tweet.get("text", tweet.get("fullText", "")) or ""
    
    # Get tweet ID and created date
    tweet_id = tweet.get("id", "")
    created_at = tweet.get("createdAt", "")
    
    return {
        "likes": likes,
        "retweets": retweets,
        "replies": replies,
        "views": views,
        "bookmarks": bookmarks,
        "author_handle": author_handle,
        "author_followers": author_followers,
        "text": text[:500],
        "id": tweet_id,
        "created_at": created_at,
        "parsed_date": parse_date(created_at),
    }

def main():
    all_results = []
    failures = []
    
    for i, handle in enumerate(HANDLES):
        print(f"[{i+1}/{len(HANDLES)}] Scanning @{handle}...", file=sys.stderr)
        tweets, error = fetch_tweets(handle)
        
        if error:
            print(f"  FAIL: {error}", file=sys.stderr)
            failures.append({"handle": handle, "error": error})
            time.sleep(1)
            continue
        
        if not tweets:
            print(f"  No tweets returned", file=sys.stderr)
            time.sleep(1)
            continue
        
        account_tweets = []
        for tweet in tweets:
            metrics = get_tweet_metrics(tweet)
            # Only include recent tweets
            if metrics["parsed_date"] and metrics["parsed_date"] >= CUTOFF:
                # Calculate engagement score
                score = metrics["likes"] + (metrics["retweets"] * 2) + (metrics["replies"] * 1.5) + (metrics["views"] / 100)
                metrics["score"] = round(score, 1)
                account_tweets.append(metrics)
        
        if account_tweets:
            # Sort by score descending
            account_tweets.sort(key=lambda x: x["score"], reverse=True)
            all_results.append({
                "handle": handle,
                "tweets": account_tweets,
                "best_score": account_tweets[0]["score"],
            })
            print(f"  Found {len(account_tweets)} qualifying tweets (best score: {account_tweets[0]['score']})", file=sys.stderr)
        else:
            print(f"  No recent high-engagement tweets", file=sys.stderr)
        
        time.sleep(1)  # Rate limiting
    
    # Sort accounts by best score descending
    all_results.sort(key=lambda x: x["best_score"], reverse=True)
    
    # Output JSON
    output = {
        "scan_date": datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC"),
        "total_accounts": len(HANDLES),
        "accounts_with_content": len(all_results),
        "failures": failures,
        "accounts": all_results,
    }
    
    print(json.dumps(output, indent=2, default=str))

if __name__ == "__main__":
    main()
