import requests
import argparse
import json
import os
import statistics
import datetime

def fetch_activity_3days(wallet):
    all_trades = []
    offset = 0
    now_ts = int(datetime.datetime.now(datetime.timezone.utc).timestamp())
    three_days = 3 * 24 * 60 * 60

    print(f"Fetching 3 days history for {wallet}...")
    while True:
        url = f"https://data-api.polymarket.com/activity?user={wallet}&limit=1000&offset={offset}"
        try:
            r = requests.get(url, timeout=15)
            if r.status_code == 200:
                data = r.json()
                items = data if isinstance(data, list) else (data.get("value", data.get("data", [])) if isinstance(data, dict) else [])
                
                if not items:
                    break
                    
                all_trades.extend(items)
                
                # Check if we have passed 3 days
                oldest_ts = items[-1].get("timestamp")
                if oldest_ts and (now_ts - oldest_ts) >= three_days:
                    break
                
                offset += 1000
            else:
                break
        except Exception as e:
            print(f"Error fetching {wallet}: {e}")
            break
            
    return all_trades

def analyze_trader(wallet, display_name):
    trades = fetch_activity_3days(wallet)
    if not trades:
        return None
        
    # Filter trades and sort ascending (oldest first)
    valid_trades = [t for t in trades if t.get("type") == "TRADE" and t.get("timestamp") and t.get("asset")]
    valid_trades.sort(key=lambda x: x["timestamp"])
    
    # Group by asset
    from collections import defaultdict
    by_asset = defaultdict(list)
    for t in valid_trades:
        by_asset[t["asset"]].append(t)
        
    total_evaluated = 0
    snipes = 0
    hold_times = []
    
    for asset, asset_trades in by_asset.items():
        # Find first BUY
        buy_ts = None
        for t in asset_trades:
            if t["side"] == "BUY":
                buy_ts = t["timestamp"]
                break
                
        if buy_ts is None:
            continue
            
        # Find first SELL after BUY (allow same second for immediate script-sells)
        sell_ts = None
        for t in asset_trades:
            if t["side"] == "SELL" and t["timestamp"] >= buy_ts:
                sell_ts = t["timestamp"]
                break
                
        if sell_ts is not None:
            total_evaluated += 1
            hold_dur = sell_ts - buy_ts
            hold_times.append(hold_dur)
            if hold_dur < 300: # Less than 5 minutes
                snipes += 1

    if total_evaluated == 0:
        return {
            "name": display_name,
            "wallet": wallet,
            "evaluated": 0,
            "snipes": 0,
            "ratio": 0.0,
            "median": 0
        }
        
    ratio = (snipes / total_evaluated) * 100
    median_hold = statistics.median(hold_times) if hold_times else 0
    
    return {
        "name": display_name,
        "wallet": wallet,
        "evaluated": total_evaluated,
        "snipes": snipes,
        "ratio": ratio,
        "median": median_hold
    }

def print_result(res):
    print(f"Trader: {res['name']} ({res['wallet']})")
    print(f"  Evaluated Pairs: {res['evaluated']}")
    print(f"  Snipe Trades (<5m): {res['snipes']}")
    if res['evaluated'] > 0:
        print(f"  Sniper Ratio: {res['ratio']:.2f}%")
        print(f"  Median Hold: {res['median']:.0f} seconds")
    print("-" * 40)

def main():
    parser = argparse.ArgumentParser(description="Analyze a trader for Liquidity Sniping.")
    parser.add_argument("--wallet", type=str, help="Single wallet to analyze")
    parser.add_argument("--all", action="store_true", help="Analyze all active traders in PolyTraderDB.trackers.json")
    args = parser.parse_args()
    
    if args.wallet:
        res = analyze_trader(args.wallet, "CLI_TEST")
        if res:
            print_result(res)
    elif args.all:
        print("Analyzing all active traders...")
        db_path = r"bin\Debug\net8.0-windows7.0\Logs\PolyTraderDB.trackers.json"
        if not os.path.exists(db_path):
            print(f"Could not find DB at {db_path}")
            return
            
        with open(db_path, "r", encoding="utf-8") as f:
            data = json.load(f)
            
        active_traders = [t for t in data if t.get("IsActive")]
        print(f"Found {len(active_traders)} active traders.")
        
        results = []
        for t in active_traders:
            wallet = t.get("WalletAddress")
            name = t.get("DisplayName")
            res = analyze_trader(wallet, name)
            if res:
                results.append(res)
        
        # Sort by worst offenders (highest sniper ratio)
        results.sort(key=lambda x: x["ratio"], reverse=True)
        
        print("\n=== SNIPING REPORT ===")
        print(f"{'Trader Name':<20} | {'Evaluated':<10} | {'Snipes':<8} | {'Ratio':<8} | {'Median Hold':<12}")
        print("-" * 75)
        for r in results:
            if r['evaluated'] > 0:
                print(f"{r['name']:<20} | {r['evaluated']:<10} | {r['snipes']:<8} | {r['ratio']:>5.1f}%   | {r['median']:>5.0f} sec")
            else:
                print(f"{r['name']:<20} | {r['evaluated']:<10} | {r['snipes']:<8} | {'N/A':<8} | {'N/A':<12}")

if __name__ == "__main__":
    main()
