#!/usr/bin/env python3
"""backtest.py — test the strategy against historical OHLCV data.

Runs the signal + risk + portfolio logic over historical candle data and prints
the resulting metrics. The actual simulation and result table are produced by
``coinbot.backtest.run_backtest`` (which prints its own table).

Flow:
  1. Load the settings (can be overridden with --mode).
  2. Determine the symbols: use --symbols if provided, otherwise scan the universe.
  3. Call ``run_backtest(ex, symbols, settings, limit=...)``.

The backtest does not send any REAL orders; it is a simulation over historical data.
"""
from __future__ import annotations

import argparse
import sys
import pathlib

sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent.parent))

from rich.console import Console

from coinbot.config import load_settings
from coinbot.exchange import Exchange, ExchangeError
from coinbot.screener import screen_universe
from coinbot.backtest import run_backtest

console = Console()


def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        prog="backtest.py",
        description="Brimoza stratejisini gecmis veri uzerinde test eder.",
    )
    parser.add_argument(
        "--symbols",
        default=None,
        help=(
            "Virgulle ayrilmis sembol listesi (or. 'BTCUSDT,ETHUSDT'). "
            "Verilmezse evren taranir ve en likit ilk N sembol kullanilir."
        ),
    )
    parser.add_argument(
        "--limit",
        type=int,
        default=500,
        help="Her sembol icin cekilecek gecmis mum sayisi (varsayilan: 500).",
    )
    parser.add_argument(
        "--mode",
        default=None,
        choices=["dry_run", "testnet", "live"],
        help="Calisma modunu config.yaml/env uzerine yaz (opsiyonel).",
    )
    return parser.parse_args(argv)


def main(argv: list[str] | None = None) -> int:
    args = _parse_args(argv)

    try:
        settings = load_settings(mode_override=args.mode)
    except (RuntimeError, ValueError) as exc:
        console.print(f"[bold red]Ayar hatasi:[/] {exc}")
        return 2

    console.print(
        f"[bold]Brimoza Backtest[/] — "
        f"mod=[cyan]{settings.mode.value}[/], "
        f"zaman dilimi=[cyan]{settings.timeframe}[/], "
        f"limit=[cyan]{args.limit}[/]"
    )

    try:
        ex = Exchange(settings)

        if args.symbols:
            symbols = [s.strip().upper() for s in args.symbols.split(",") if s.strip()]
        else:
            with console.status("[bold]Evren taraniyor (likidite/hacim)..."):
                symbols = screen_universe(ex, settings)[: settings.universe.max_symbols]
    except ExchangeError as exc:
        console.print(
            f"[bold red]Borsa hatasi:[/] {exc}\n"
            "[yellow]Internet baglantinizi kontrol edin; Binance API gecici olarak "
            "erisilemez olabilir.[/]"
        )
        return 1
    except Exception as exc:  # noqa: BLE001 - user-friendly last resort
        console.print(
            f"[bold red]Beklenmeyen ag/hatasi:[/] {exc}\n"
            "[yellow]Internet baglantinizi kontrol edip tekrar deneyin.[/]"
        )
        return 1

    if not symbols:
        console.print(
            "[yellow]Test edilecek sembol bulunamadi. --symbols ile sembol belirtin "
            "veya config.yaml icindeki universe esiklerini gevsetiniz.[/]"
        )
        return 0

    console.print(f"[dim]{len(symbols)} sembol test ediliyor: {', '.join(symbols)}[/]")

    try:
        # run_backtest prints its own result table.
        run_backtest(ex, symbols, settings, limit=args.limit)
    except ExchangeError as exc:
        console.print(f"[bold red]Borsa hatasi (backtest sirasinda):[/] {exc}")
        return 1
    except Exception as exc:  # noqa: BLE001 - user-friendly last resort
        console.print(f"[bold red]Backtest sirasinda beklenmeyen hata:[/] {exc}")
        return 1

    return 0


if __name__ == "__main__":
    raise SystemExit(main())
