"""
Тесты _build_dataset: проверяет корректную сборку признаков для RF.
"""
import numpy as np
import pandas as pd


def test_build_dataset_basic():
    """_build_dataset возвращает корректную форму с base + expert features."""
    # Создаём минимальный ensemble mock
    class MockExpert:
        pass

    class MockEnsemble:
        def __init__(self):
            self.expert_names = ['momentum', 'volume_profile']

    from models.moe import _build_dataset
    from models.experts import HORIZONS, MULTICLASS_NAMES

    n = 50
    df = pd.DataFrame({
        'rsi_signal': np.random.uniform(-1, 1, n),
        'volume_signal': np.random.uniform(-1, 1, n),
        'close_to_sma_10': np.random.uniform(-0.05, 0.05, n),
    })

    ensemble = MockEnsemble()

    # Signals: non-multiclass (momentum) + multiclass (volume_profile)
    signals = {}
    for h in HORIZONS:
        signals[f'momentum_h{h}_signal'] = np.random.uniform(-1, 1, n)
        signals[f'momentum_h{h}_confidence'] = np.random.uniform(0, 1, n)
    signals['volume_profile_prob_0'] = np.random.uniform(0, 1, n)
    signals['volume_profile_prob_1'] = np.random.uniform(0, 1, n)
    signals['volume_profile_prob_2'] = np.random.uniform(0, 1, n)

    feature_cols = ['rsi_signal', 'volume_signal', 'close_to_sma_10']
    X = _build_dataset(df, signals, ensemble, feature_cols)

    # 3 base + 4 horizons*2 (momentum) + 3 probs (volume_profile) = 3 + 8 + 3 = 14
    expected_cols = len(feature_cols) + len(HORIZONS) * 2 + 3
    assert X.shape == (n, expected_cols), f"Expected ({n}, {expected_cols}), got {X.shape}"
    assert np.all(np.isfinite(X)), "All values must be finite"
    assert not np.any(np.isnan(X)), "No NaNs allowed"


def test_build_dataset_empty_signals():
    """_build_dataset с пустыми сигналами (no experts)."""
    from models.moe import _build_dataset

    n = 20
    df = pd.DataFrame({
        'rsi_signal': np.random.uniform(-1, 1, n),
    })

    class MockEnsemble:
        expert_names = []

    signals = {}
    X = _build_dataset(df, signals, MockEnsemble(), ['rsi_signal'])
    assert X.shape == (n, 1), f"Expected ({n}, 1), got {X.shape}"
