"""Backtester for the autonomous trading engine.

Pure computation module that assembles backtest results from
pre-computed trade data and daily returns.  The actual replay logic
(fetching historical data, simulating decisions) requires DB access
and will be wired in the integration layer.  This module provides
the pure computation for result assembly.
"""

from __future__ import annotations

import uuid
from dataclasses import dataclass, field
from datetime import date

from services.trading.models import ClosedTrade
from services.trading.performance_tracker import PerformanceComputer

# ---------------------------------------------------------------------------
# Data classes
# ---------------------------------------------------------------------------


@dataclass
class BacktestConfig:
    """Configuration for a backtest run."""

    start_date: date
    end_date: date
    initial_capital: float
    risk_tier: str  # conservative | moderate | aggressive


@dataclass
class BacktestResult:
    """Output of a completed backtest run."""

    backtest_id: str
    config: BacktestConfig
    total_return: float
    sharpe_ratio: float
    max_drawdown: float
    win_rate: float
    profit_factor: float
    trade_count: int
    trade_log: list[dict] = field(default_factory=list)
    equity_curve: list[dict] = field(default_factory=list)


# ---------------------------------------------------------------------------
# Engine
# ---------------------------------------------------------------------------


class BacktestEngine:
    """Assembles a BacktestResult from pre-computed trade data.

    Uses :class:`PerformanceComputer` to derive metrics from closed
    trades and daily returns, then packages everything into a
    :class:`BacktestResult`.
    """

    def __init__(self) -> None:
        self._perf = PerformanceComputer()

    def compute_result(
        self,
        config: BacktestConfig,
        trades: list[ClosedTrade],
        daily_returns: list[float],
        equity_curve: list[dict],
    ) -> BacktestResult:
        """Build a :class:`BacktestResult` from raw simulation outputs.

        Args:
            config: The backtest configuration that was used.
            trades: Closed trades produced by the simulation.
            daily_returns: Daily return percentages for the simulated period.
            equity_curve: List of ``{"date": ..., "portfolio_value": ...}``
                dicts representing the equity curve.

        Returns:
            A fully populated :class:`BacktestResult`.
        """
        metrics = self._perf.compute_metrics(
            closed_trades=trades,
            portfolio_value=config.initial_capital,
            active_pool=config.initial_capital,
            reserve_pool=0.0,
            daily_pnl=0.0,
            unrealized_pnl=0.0,
            portfolio_heat=0.0,
            daily_returns=daily_returns,
        )

        trade_log = [self._perf.compute_trade_metrics(t) for t in trades]

        total_return = (
            sum(t.pnl for t in trades) / config.initial_capital
            if config.initial_capital > 0
            else 0.0
        )

        return BacktestResult(
            backtest_id=str(uuid.uuid4()),
            config=config,
            total_return=total_return,
            sharpe_ratio=metrics.sharpe_ratio,
            max_drawdown=metrics.max_drawdown,
            win_rate=metrics.win_rate,
            profit_factor=metrics.profit_factor,
            trade_count=len(trades),
            trade_log=trade_log,
            equity_curve=equity_curve,
        )
