"""
Batch optimizer: runs auto_optimize_loop.py on all crypto assets × all timeframes.

Usage:
    python3 run_all_crypto.py                          # use auto_optimize_loop.py default (3 iters × 50M)
    python3 run_all_crypto.py --hours 0.5              # override per-run duration
    python3 run_all_crypto.py --skip BINANCE_LINKUSD-1D  # skip known bad exports
"""

import subprocess
import sys
import argparse
import time
from datetime import datetime, timedelta

CRYPTO_ASSETS = [
    "COINBASE_BTCUSD",
    "COINBASE_ETHUSD",
    "BINANCE_SOLUSD",
    "BINANCE_LINKUSD",
]

TIMEFRAMES = ["4H", "6H", "8H", "12H", "1D"]
_TF_TO_MIN = {"4H": "240", "6H": "360", "8H": "480", "12H": "720", "1D": "1D"}

DEFAULT_SKIP: set = set()


def main():
    parser = argparse.ArgumentParser(description="Batch optimizer across all crypto assets and timeframes")
    parser.add_argument("--hours", type=float, default=None,
                        help="Hours per asset/timeframe combo. If omitted, uses auto_optimize_loop.py default (3 iterations × 50M samples).")
    parser.add_argument("--skip", nargs="*", default=[], metavar="ASSET-TF",
                        help="Additional combos to skip, e.g. BINANCE_LINKUSD-1D")
    parser.add_argument("--no-default-skip", action="store_true",
                        help="(No-op, kept for compatibility)")
    parser.add_argument("--search", type=str, default="random", choices=["random", "optuna"],
                        help="Search strategy: 'random' (default) or 'optuna' (biased sampling)")
    parser.add_argument("--regime", type=str, default="all", choices=["all", "bull", "bear", "sideways"],
                        help="MVRV regime filter for IS training bars (default: all)")
    args = parser.parse_args()

    skip_set = set(args.skip)
    if not args.no_default_skip:
        skip_set |= DEFAULT_SKIP

    combos = []
    for asset in CRYPTO_ASSETS:
        for tf in TIMEFRAMES:
            key = f"{asset}-{tf}"
            if key in skip_set:
                print(f"[SKIP] {key} (in skip list)")
                continue
            combos.append((asset, tf, f"data/mlp/{asset}, {_TF_TO_MIN.get(tf, tf)}.csv"))

    total = len(combos)
    hours_label = f"{args.hours}h" if args.hours is not None else "default"
    if args.hours is not None:
        estimated_total_hours = total * args.hours
        eta = datetime.now() + timedelta(hours=estimated_total_hours)
        print(f"Running {total} combinations × {hours_label} each = ~{estimated_total_hours:.1f}h total")
        print(f"Estimated completion: {eta.strftime('%Y-%m-%d %H:%M:%S')}")
    else:
        print(f"Running {total} combinations × {hours_label} duration each")
    print(f"Started at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")

    for i, (asset, tf, data_path) in enumerate(combos, 1):
        label = f"{asset}-{tf}"
        print(f"\n{'='*60}")
        print(f"[{i}/{total}] {label}  ({hours_label})")
        print(f"  Started: {datetime.now().strftime('%H:%M:%S')}")
        print(f"{'='*60}")

        cmd = [sys.executable, "tools/auto_optimize_loop.py", "--data", data_path,
               "--search", args.search, "--regime", args.regime]
        if args.hours is not None:
            cmd += ["--hours", str(args.hours)]

        start = time.time()
        result = subprocess.run(cmd)
        elapsed = time.time() - start

        status = "OK" if result.returncode == 0 else f"EXIT {result.returncode}"
        print(f"\n[{i}/{total}] {label} finished in {elapsed/60:.1f}m  [{status}]")

        remaining = total - i
        if remaining > 0:
            if args.hours is not None:
                eta = datetime.now() + timedelta(hours=remaining * args.hours)
                print(f"  Remaining: {remaining} combos, ETA {eta.strftime('%H:%M:%S')}")
            else:
                print(f"  Remaining: {remaining} combos")

    print(f"\n{'='*60}")
    print(f"All done. Finished at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")

    # Auto-update Pine presets with latest winner params
    print("\n[PRESETS] Updating Pine file with latest winner params...")
    preset_result = subprocess.run([sys.executable, "tools/generate_pine_presets.py"])
    if preset_result.returncode == 0:
        print("[PRESETS] Pine file updated — paste strategies/strategy_activation_scores.pine into TradingView.")
    else:
        print("[PRESETS] WARNING: generate_pine_presets.py failed. Run manually.")


if __name__ == "__main__":
    main()
