from backtesting import engine
from ml.artifacts import ML_ARTIFACT_SCHEMA_VERSION, REQUIRED_WEIGHT_KEYS
from scoring.policy import SCORE_VERSION


def _weights(focus):
    weights = {key: 0.0 for key in REQUIRED_WEIGHT_KEYS}
    weights[focus] = 1.0
    return weights


def _artifact(with_folds=True):
    artifact = {
        "artifact_schema_version": ML_ARTIFACT_SCHEMA_VERSION,
        "score_version": SCORE_VERSION,
        "weights": _weights("fear_greed"),
        "provenance": {
            "validation_method": "purged_expanding_window",
            "label_horizon_days": 365,
            "weight_scope": "full_history_fit",
            "training_date_range": {"start": "2018-01-01", "end": "2024-01-01"},
            "trained_at": "2026-07-01T00:00:00+00:00",
        },
        "cv_results": {"folds": []},
    }
    if with_folds:
        artifact["cv_results"]["folds"] = [
            {
                "fold": 1,
                "weights": _weights("drawdown"),
                "date_ranges": {"validation": "2020-01-01 to 2020-12-31"},
            },
            {
                "fold": 2,
                "weights": _weights("nupl"),
                "date_ranges": {"validation": "2021-01-01 to 2021-12-31"},
            },
        ]
    return artifact


def test_ml_backtest_plan_prefers_fold_weights_and_marks_them_oos():
    plan = engine._build_ml_backtest_plan(_artifact(with_folds=True))

    weights, fold = engine._weights_for_backtest_date("2021-06-01", plan)

    assert weights == _weights("nupl")
    assert fold == 2
    assert plan["evaluation_scope"] == "out_of_sample_validation_folds"
    assert plan["is_out_of_sample"] is True
    assert plan["weighting_source"] == "fold_specific_weights"
    assert engine._weights_for_backtest_date("2019-12-31", plan) == (None, None)


def test_full_history_weights_are_explicitly_not_oos():
    plan = engine._build_ml_backtest_plan(_artifact(with_folds=False))

    weights, fold = engine._weights_for_backtest_date("2021-06-01", plan)

    assert weights == _weights("fear_greed")
    assert fold is None
    assert plan["evaluation_scope"] == "in_sample_full_history_weights"
    assert plan["is_out_of_sample"] is False
    assert plan["weighting_source"] == "final_full_history_weights"
