//! DQN model integration test
//!
//! Verifies: create model -> forward pass -> valid output range
//! Uses lightweight config for fast execution (<10s)

use ml::dqn::dqn::DQNConfig;
use ml::ensemble::adapters::DqnInferenceAdapter;
use ml::ensemble::inference_adapter::{FeatureVector, ModelInferenceAdapter};

fn small_dqn_config() -> DQNConfig {
    DQNConfig {
        state_dim: 51,
        num_actions: 5,
        hidden_dims: vec![32, 32],
        ..Default::default()
    }
}

#[test]
fn test_dqn_adapter_produces_valid_prediction() {
    let adapter = DqnInferenceAdapter::new(small_dqn_config())
        .expect("DqnInferenceAdapter::new should succeed");

    assert_eq!(adapter.model_name(), "DQN");
    assert!(adapter.is_ready());

    let fv = FeatureVector {
        values: vec![0.1; 51],
        timestamp: 1_700_000_000_000_000,
    };

    let pred = adapter.predict(&fv).expect("DQN predict should succeed");

    assert!(
        pred.direction >= -1.0 && pred.direction <= 1.0,
        "direction {} out of [-1,1]",
        pred.direction
    );
    assert!(
        pred.confidence >= 0.0 && pred.confidence <= 1.0,
        "confidence {} out of [0,1]",
        pred.confidence
    );
    assert!(pred.direction.is_finite(), "direction must not be NaN/Inf");
    assert!(pred.confidence.is_finite(), "confidence must not be NaN/Inf");
    assert!(
        pred.metadata.q_values.is_some(),
        "DQN should include Q-values in metadata"
    );
}

#[test]
fn test_dqn_deterministic_inference() {
    let adapter = DqnInferenceAdapter::new(small_dqn_config())
        .expect("DqnInferenceAdapter::new should succeed");

    let fv = FeatureVector {
        values: vec![0.5; 51],
        timestamp: 1_700_000_000_000_000,
    };

    let pred1 = adapter.predict(&fv).expect("predict 1");
    let pred2 = adapter.predict(&fv).expect("predict 2");

    assert_eq!(
        pred1.direction, pred2.direction,
        "DQN inference should be deterministic"
    );
    assert_eq!(
        pred1.confidence, pred2.confidence,
        "DQN confidence should be deterministic"
    );
}

#[test]
fn test_dqn_different_inputs_different_outputs() {
    let adapter = DqnInferenceAdapter::new(small_dqn_config())
        .expect("DqnInferenceAdapter::new should succeed");

    let fv_low = FeatureVector {
        values: vec![0.0; 51],
        timestamp: 1_700_000_000_000_000,
    };
    let fv_high = FeatureVector {
        values: vec![1.0; 51],
        timestamp: 1_700_000_000_000_000,
    };

    let pred_low = adapter.predict(&fv_low).expect("predict low");
    let pred_high = adapter.predict(&fv_high).expect("predict high");

    assert!(pred_low.direction.is_finite());
    assert!(pred_high.direction.is_finite());
}
