#!/usr/bin/env python3
"""GARP scan - batch download approach for speed."""
import yfinance as yf
import json, sys

sys.stdout.reconfigure(line_buffering=True)

EXCLUDE = {"BAC", "CFG", "FITB", "INCY"}

with open("broad_tickers.txt") as f:
    tickers = [l.strip().replace(".", "-") for l in f if l.strip()]

print(f"Screening {len(tickers)} tickers in batches...")

passed = []
batch_size = 20

for batch_start in range(0, len(tickers), batch_size):
    batch = tickers[batch_start:batch_start + batch_size]
    batch = [t for t in batch if t not in EXCLUDE]
    if not batch:
        continue
    
    print(f"Batch {batch_start}-{batch_start+len(batch)} / {len(tickers)}...")
    
    try:
        data = yf.Tickers(" ".join(batch))
        for tick in batch:
            try:
                info = data.tickers[tick].info or {}
                
                mc = info.get("marketCap", 0) or 0
                if mc < 5e9: continue
                
                tpe = info.get("trailingPE")
                if not tpe or tpe >= 25 or tpe <= 0: continue
                    
                fpe = info.get("forwardPE")
                if not fpe or fpe >= 15 or fpe <= 0: continue
                
                rg = info.get("revenueGrowth")
                if rg is None or rg < 0.10: continue
                
                eg = info.get("earningsGrowth")
                if eg is None or eg < 0.15: continue
                
                roe = info.get("returnOnEquity")
                if roe is None or roe < 0.05: continue
                
                peg = info.get("pegRatio")
                if peg is not None and peg > 1.2: continue
                
                dte = info.get("debtToEquity")
                if dte is not None and dte > 35: continue
                
                entry = {
                    "ticker": tick,
                    "name": info.get("longName", tick),
                    "market_cap_B": round(mc / 1e9, 1),
                    "trailing_pe": round(tpe, 2),
                    "forward_pe": round(fpe, 2),
                    "peg": round(peg, 2) if peg else None,
                    "revenue_growth_pct": round(rg * 100, 1),
                    "earnings_growth_pct": round(eg * 100, 1),
                    "roe_pct": round(roe * 100, 1),
                    "debt_to_equity": round(dte, 1) if dte else None,
                    "sector": info.get("sector"),
                    "industry": info.get("industry"),
                }
                passed.append(entry)
                print(f"  ✅ {tick}: PE={tpe:.1f} FPE={fpe:.1f} RG={rg*100:.0f}% EG={eg*100:.0f}% ROE={roe*100:.0f}%")
            except:
                continue
    except Exception as e:
        print(f"  Batch error: {e}")
        continue

passed.sort(key=lambda x: x.get("forward_pe", 99))

with open("garp-expanded-scan.json", "w") as f:
    json.dump(passed, f, indent=2)

print(f"\nDone! {len(passed)} stocks passed GARP screen")
for s in passed:
    print(f"  {s['ticker']:6s} ${s['market_cap_B']:6.1f}B  PE:{s['trailing_pe']:5.1f}  FPE:{s['forward_pe']:5.1f}  RG:{s['revenue_growth_pct']:5.1f}%  EG:{s['earnings_growth_pct']:5.1f}%  ROE:{s['roe_pct']:5.1f}%")
