"""
Unit tests for Backtester, WalkForwardValidator, and PaperOutcomeTracker
"""
import pytest
from python.research.backtester import Backtester
from python.research.walk_forward import WalkForwardValidator
from python.research.outcome_tracker import PaperOutcomeTracker

def make_test_candles(count=80, trend="up"):
    candles = []
    price = 24000.0
    for i in range(count):
        drift = 10.0 if trend == "up" else -10.0
        o = price
        c = price + drift
        h = max(o, c) + 5.0
        l = min(o, c) - 5.0
        candles.append({
            "timestamp": i,
            "open": o,
            "high": h,
            "low": l,
            "close": c,
            "volume": 10000,
            "oi": 150000
        })
        price = c
    return candles

def test_backtester_runs_and_calculates_costs():
    candles = make_test_candles(count=60, trend="up")
    bt = Backtester(lot_size=25, slippage_pts=1.0)
    res = bt.run_backtest(candles)
    assert "total_trades" in res
    assert "gross_pnl" in res
    assert "net_pnl" in res
    assert "win_rate_pct" in res
    assert "profit_factor" in res

def test_walk_forward_validation():
    candles = make_test_candles(count=100, trend="up")
    wf = WalkForwardValidator(in_sample_pct=0.7)
    res = wf.run_walk_forward(candles)
    assert res["status"] == "COMPLETED"
    assert "in_sample_result" in res
    assert "out_of_sample_result" in res
    assert "robustness_ratio" in res

def test_paper_outcome_tracker_target_hit():
    setup = {
        "id": 101,
        "candidate_type": "BUY_CE",
        "entry_price": 24050.0,
        "stop_loss": 23950.0,
        "target_1": 24150.0,
        "target_2": 24200.0
    }
    # Future candles trigger entry then target
    subsequent = [
        {"timestamp": 1, "open": 24040, "high": 24060, "low": 24030, "close": 24055, "volume": 1000},
        {"timestamp": 2, "open": 24055, "high": 24160, "low": 24050, "close": 24155, "volume": 1000},
    ]
    outcome = PaperOutcomeTracker.evaluate_setup_outcome(setup, subsequent, lot_size=25)
    assert outcome["triggered"] is True
    assert outcome["outcome"] == "TARGET_REACHED"
    assert outcome["is_profitable"] is True
    assert outcome["final_pnl"] > 0
