"""Walk-Forward Validation with Purging and Embargo."""
from __future__ import annotations

from typing import Any, Sequence

from backend.app.backtesting.engine import BacktestEngine
from backend.app.backtesting.metrics import BacktestReport
from backend.app.schemas.market import Candle


class WalkForwardValidator:
    """Executes rolling out-of-sample evaluations with strict temporal isolation."""

    def __init__(
        self,
        train_bars: int = 200,
        val_bars: int = 50,
        test_bars: int = 50,
        embargo_bars: int = 5,
    ) -> None:
        self.train_bars = train_bars
        self.val_bars = val_bars
        self.test_bars = test_bars
        self.embargo_bars = embargo_bars
        self.engine = BacktestEngine()

    def run_validation(self, candles: Sequence[Candle]) -> dict[str, Any]:
        """Perform sequential walk-forward window analysis."""
        total_len = len(candles)
        window_size = self.train_bars + self.val_bars + self.test_bars + (2 * self.embargo_bars)

        if total_len < window_size:
            # Fallback for short dataset
            report, trades, _ = self.engine.run(candles)
            return {
                "windows_evaluated": 1,
                "overall_report": report,
                "trade_count": len(trades),
            }

        reports: list[BacktestReport] = []
        step = self.test_bars

        for start in range(0, total_len - window_size + 1, step):
            test_start = start + self.train_bars + self.embargo_bars + self.val_bars + self.embargo_bars
            test_end = test_start + self.test_bars
            test_slice = candles[test_start:test_end]

            # Evaluate untouched out-of-sample test window
            rep, _, _ = self.engine.run(test_slice)
            reports.append(rep)

        avg_return = sum(r.total_return_pct for r in reports) / len(reports) if reports else 0.0
        avg_sharpe = sum(r.sharpe_ratio for r in reports) / len(reports) if reports else 0.0
        avg_max_dd = sum(r.max_drawdown_pct for r in reports) / len(reports) if reports else 0.0

        return {
            "windows_evaluated": len(reports),
            "average_oos_return_pct": round(avg_return, 2),
            "average_oos_sharpe": round(avg_sharpe, 2),
            "average_oos_max_drawdown_pct": round(avg_max_dd, 2),
            "individual_reports": [r.__dict__ for r in reports],
        }


walk_forward_validator = WalkForwardValidator()
