"""
Batch optimizer: runs auto_optimize_loop.py on COINBASE_BTCUSD across all timeframes.

Usage:
    python3 run_btc.py                  # use auto_optimize_loop.py default (3 iters × 50M)
    python3 run_btc.py --hours 10       # 10h total budget, split evenly across all 5 TFs (2h each)
    python3 run_btc.py --hours 8 --tfs 6H 8H 12H 1D  # 8h split across 4 TFs (2h each)
"""

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

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


EXAMPLES = """
examples:
  python3 run_btc.py --hours 10
      10h total ÷ 5 TFs = 2h each (4H, 6H, 8H, 12H, 1D)

  python3 run_btc.py --hours 8 --tfs 6H 8H 12H 1D
      8h total ÷ 4 TFs = 2h each (skips 4H)

  python3 run_btc.py --tfs 6H
      Single timeframe, default iteration count

  python3 run_btc.py
      All 5 TFs, default iteration count (3 iters × 50M samples each)
"""


def main():
    parser = argparse.ArgumentParser(
        description="Batch optimizer for COINBASE_BTCUSD across all timeframes.",
        epilog=EXAMPLES,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument("--hours", type=float, default=None,
                        help="Total hour budget divided evenly across timeframes. "
                             "E.g. --hours 10 with 5 TFs = 2h each.")
    parser.add_argument("--tfs", nargs="*", default=None, metavar="TF",
                        help="Timeframes to run (default: all 5). "
                             "E.g. --tfs 6H 8H 12H 1D")
    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)")
    parser.add_argument("--tighten", action="store_true",
                        help="Auto-apply q5-q95 range tightening after each iteration (tighten_params.py --apply)")
    args = parser.parse_args()

    tfs = [tf.upper() for tf in args.tfs] if args.tfs else TIMEFRAMES
    combos = [(ASSET, tf, f"data/mlp/{ASSET}, {_TF_TO_MIN.get(tf, tf)}.csv") for tf in tfs]
    total = len(combos)

    if args.hours is not None:
        hours_per_tf = args.hours / total
        eta = datetime.now() + timedelta(hours=args.hours)
        print(f"Total budget: {args.hours}h  ÷  {total} timeframes = {hours_per_tf:.2f}h each")
        print(f"Estimated completion: {eta.strftime('%Y-%m-%d %H:%M:%S')}")
    else:
        hours_per_tf = None
        print(f"Running {total} timeframes × default 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}"
        per_tf_label = f"{hours_per_tf:.2f}h" if hours_per_tf is not None else "default"
        print(f"\n{'='*60}")
        print(f"[{i}/{total}] {label}  ({per_tf_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 hours_per_tf is not None:
            cmd += ["--hours", str(hours_per_tf)]
        if args.tighten:
            cmd += ["--tighten"]

        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 hours_per_tf is not None:
                eta = datetime.now() + timedelta(hours=remaining * hours_per_tf)
                print(f"  Remaining: {remaining} timeframes, ETA {eta.strftime('%H:%M:%S')}")
            else:
                print(f"  Remaining: {remaining} timeframes")

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


if __name__ == "__main__":
    main()
