#!/usr/bin/env python3
"""
Backtest all 100 complementary day-trading ideas.

Example::

    cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 .venv/bin/python \\
        RenTech/strategy_stack/run_day_trading_100_complement.py \\
        --start 2022-01-03 --end 2025-12-31 \\
        --out-prefix RenTech/data/logs/day_trading_100_complement
"""

from __future__ import annotations

import argparse
import json
import sys
from pathlib import Path

import pandas as pd

_REPO = Path(__file__).resolve().parents[2]
if str(_REPO) not in sys.path:
    sys.path.insert(0, str(_REPO))

from RenTech.strategy_stack.alpaca_minute_loader import DEFAULT_ALPACA_RTH_DIR
from RenTech.strategy_stack.day_trading_100_complement import IDEA_REGISTRY, load_context, run_all

LOGS = _REPO / "RenTech" / "data" / "logs"


def main() -> None:
    ap = argparse.ArgumentParser(description=__doc__.split("\n\n")[0])
    ap.add_argument("--data-dir", type=Path, default=DEFAULT_ALPACA_RTH_DIR)
    ap.add_argument("--start", default="2022-01-03")
    ap.add_argument("--end", default="2025-12-31")
    ap.add_argument("--max-sp100", type=int, default=80)
    ap.add_argument("--ids", default="", help="Comma-separated idea IDs (default: all)")
    ap.add_argument("--skip-slow", action="store_true", help="Skip SP100 slope XS ideas")
    ap.add_argument("--out-prefix", type=Path, default=LOGS / "day_trading_100_complement")
    args = ap.parse_args()

    ids = [x.strip() for x in args.ids.split(",") if x.strip()] or None
    ctx = load_context(args.data_dir, args.start, args.end, max_sp100=int(args.max_sp100))
    print(f"\nRunning {len(ids) if ids else len(IDEA_REGISTRY)} ideas …", flush=True)
    results = run_all(ctx, ids=ids, skip_slow=bool(args.skip_slow))

    rows = [r.to_row() for r in results]
    df = pd.DataFrame(rows).sort_values(["status", "sharpe"], ascending=[True, False])
    out = args.out_prefix.expanduser().resolve()
    out.parent.mkdir(parents=True, exist_ok=True)
    df.to_csv(f"{out}_results.csv", index=False)

    n_ok = int((df["status"] == "ok").sum())
    n_skip = int((df["status"] == "skip").sum())
    n_err = int((df["status"] == "error").sum())
    top = df[(df["status"] == "ok") & (df["n_trades"] >= 20)].head(20)

    cmd = (
        f"cd {_REPO} && PYTHONUNBUFFERED=1 .venv/bin/python "
        f"RenTech/strategy_stack/run_day_trading_100_complement.py "
        f"--start {args.start} --end {args.end} --out-prefix {out}"
    )
    meta = {
        "command": cmd,
        "start": args.start,
        "end": args.end,
        "max_sp100": args.max_sp100,
        "n_ok": n_ok,
        "n_skip": n_skip,
        "n_error": n_err,
        "top20_by_sharpe_min20trades": top.to_dict(orient="records"),
    }
    Path(f"{out}_meta.json").write_text(json.dumps(meta, indent=2, default=str) + "\n")

    lines = [
        f"command: {cmd}",
        f"window: {args.start} → {args.end}",
        f"ok={n_ok} skip={n_skip} error={n_err}",
        "",
        "TOP (ok, n_trades>=20) by Sharpe:",
        top[["idea_id", "name", "sharpe", "total_return_pct", "n_trades", "avg_pnl_pct", "win_rate_pct"]].to_string(index=False)
        if not top.empty
        else "(none)",
        "",
    ]
    Path(f"{out}_metrics.txt").write_text("\n".join(lines) + "\n")

    print(f"\n=== SUMMARY ok={n_ok} skip={n_skip} error={n_err} ===", flush=True)
    if not top.empty:
        print(top[["idea_id", "name", "sharpe", "n_trades", "avg_pnl_pct"]].to_string(index=False), flush=True)
    print(f"\nWrote {out}_results.csv", flush=True)


if __name__ == "__main__":
    main()
