"""
Тесты _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

    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()

    # All experts are non-multiclass (MULTICLASS_NAMES is empty) → каждый 4 horizons × 2
    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)
    for h in HORIZONS:
        signals[f'volume_profile_h{h}_signal'] = np.random.uniform(-1, 1, n)
        signals[f'volume_profile_h{h}_confidence'] = 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) + 4 horizons*2 (volume_profile) = 3 + 8 + 8 = 19
    expected_cols = len(feature_cols) + len(HORIZONS) * 2 * 2
    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}"
