#!/usr/bin/env python3
"""run.py — Starts the Brimoza live/simulated trading loop.

Prints a clear banner depending on the run mode:
  - DRY_RUN : green info banner (simulated, no risk).
  - TESTNET : yellow info banner (fake money, real API).
  - LIVE    : RED warning box — the user is required to type "LIVE".
              This is an ADDITIONAL safety step on top of the
              CONFIRM_LIVE_TRADING environment-variable gate in config.py.

After the confirmations, the main loop starts via ``TradingBot(settings).run_forever()``.
"""
from __future__ import annotations

import argparse
import logging
import sys
import pathlib
from logging.handlers import RotatingFileHandler

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

from rich.align import Align
from rich.console import Console
from rich.panel import Panel
from rich.text import Text

from coinbot.config import Mode, load_settings
from coinbot.bot import TradingBot

console = Console()


def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        prog="run.py",
        description="Brimoza isleme dongusunu baslatir.",
    )
    parser.add_argument(
        "--mode",
        default=None,
        choices=["dry_run", "testnet", "live"],
        help="Calisma modunu config.yaml/env uzerine yaz (opsiyonel).",
    )
    parser.add_argument(
        "--config",
        default="config.yaml",
        help="Kullanilacak yapilandirma dosyasi (varsayilan config.yaml).",
    )
    return parser.parse_args(argv)


def _banner(settings) -> None:
    """Prints a large colored banner based on the mode; asks for confirmation if needed."""
    mode = settings.mode

    if mode == Mode.DRY_RUN:
        title = Text("DRY RUN — SIMULASYON", style="bold green")
        body = Text(
            "Gercek emir GONDERILMEZ. Tum islemler paper cuzdan uzerinde "
            "simule edilir. Risk yoktur.",
            style="green",
        )
        console.print(
            Panel(Align.center(body), title=title, border_style="green", padding=(1, 4))
        )
    elif mode == Mode.TESTNET:
        title = Text("TESTNET — SAHTE PARA", style="bold yellow")
        body = Text(
            "Binance Spot Testnet kullaniliyor. Gercek API cagrilari yapilir "
            "ancak para SAHTEDIR.",
            style="yellow",
        )
        console.print(
            Panel(Align.center(body), title=title, border_style="yellow", padding=(1, 4))
        )
    else:  # Mode.LIVE
        warning = Text()
        warning.append("!!! DIKKAT !!!\n\n", style="bold white on red")
        warning.append(
            "GERCEK PARA ILE ISLEM YAPILACAK\n\n", style="bold red"
        )
        warning.append(
            "Bu mod GERCEK Binance hesabinizda GERCEK emirler gonderir ve "
            "gercek para kaybedebilirsiniz.",
            style="red",
        )
        console.print(
            Panel(
                Align.center(warning),
                title=Text("LIVE — GERCEK PARA", style="bold white on red"),
                border_style="red",
                padding=(1, 4),
            )
        )


def _confirm_live() -> bool:
    """In LIVE mode, explicitly asks the user to type 'LIVE'."""
    console.print(
        "[bold red]Devam etmek icin buyuk harflerle [white on red] LIVE [/] yazip Enter'a basin "
        "(iptal icin baska bir sey yazin):[/]"
    )
    try:
        answer = input("> ").strip()
    except (EOFError, KeyboardInterrupt):
        console.print("\n[yellow]Iptal edildi.[/]")
        return False
    if answer != "LIVE":
        console.print("[yellow]Onay alinamadi; cikiliyor.[/]")
        return False
    console.print("[bold red]LIVE onaylandi. Dongu baslatiliyor...[/]")
    return True


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

    try:
        settings = load_settings(args.config, mode_override=args.mode)
    except (RuntimeError, ValueError) as exc:
        # The LIVE env gate in config.py also passes through here (RuntimeError).
        console.print(f"[bold red]Ayar/guvenlik hatasi:[/] {exc}")
        return 2

    # Configure logging: write INFO to both the file (engine.log_file) and the console.
    # A persistent log is essential for a trading bot (forward observation + live auditing).
    log_path = pathlib.Path(settings.engine.log_file)
    log_path.parent.mkdir(parents=True, exist_ok=True)
    # ROTATION: a plain FileHandler grows the file WITHOUT LIMIT; a long-running bot could
    # fill the disk. Cap it with 10 MB x 5 files = ~50 MB ceiling.
    logging.basicConfig(
        level=logging.INFO,
        format="%(asctime)s %(levelname)s %(name)s: %(message)s",
        handlers=[
            RotatingFileHandler(
                log_path, maxBytes=10 * 1024 * 1024, backupCount=5, encoding="utf-8"
            ),
            logging.StreamHandler(),
        ],
    )

    _banner(settings)

    if settings.mode == Mode.LIVE:
        if not _confirm_live():
            return 1

    console.print(
        f"[bold]Brimoza[/] baslatiliyor — "
        f"mod=[cyan]{settings.mode.value}[/], "
        f"zaman dilimi=[cyan]{settings.timeframe}[/], "
        f"poll=[cyan]{settings.engine.poll_interval_seconds}s[/]"
    )

    try:
        bot = TradingBot(settings)
        bot.run_forever()
    except KeyboardInterrupt:
        console.print("\n[yellow]Kullanici tarafindan durduruldu (Ctrl-C).[/]")
        return 0
    except Exception as exc:  # noqa: BLE001 - user-friendly last resort
        console.print(f"[bold red]Dongu beklenmeyen hatayla durdu:[/] {exc}")
        return 1

    return 0


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