//! Integration tests for ML models in backtesting framework

use backtesting::{
    create_adaptive_strategy_with_config, AdaptiveStrategyConfig, BacktestConfig, BacktestEngine,
    FeatureSettings, RiskSettings,
};
use rust_decimal::Decimal;

#[tokio::test]
async fn test_dqn_strategy_integration() {
    // Create backtesting engine
    let config = BacktestConfig {
        initial_capital: Decimal::from(100000),
        ..Default::default()
    };

    let mut engine = BacktestEngine::new(config).await.unwrap();

    // Set adaptive strategy with DQN model
    let adaptive_config = AdaptiveStrategyConfig {
        active_models: vec!["DQN".to_string()],
        ..AdaptiveStrategyConfig::default()
    };
    let dqn_strategy = Box::new(create_adaptive_strategy_with_config(adaptive_config));
    engine.set_strategy(dqn_strategy).await.unwrap();

    // Verify strategy is set
    let state = engine.get_state().await;
    assert!(!state.is_running);

    // Note: Actual backtesting would require market data loading
    // This test validates the integration is working
}

#[tokio::test]
async fn test_ppo_strategy_integration() {
    let config = BacktestConfig::default();
    let mut engine = BacktestEngine::new(config).await.unwrap();

    // Set adaptive strategy with PPO model
    let adaptive_config = AdaptiveStrategyConfig {
        active_models: vec!["PPO".to_string()],
        ..AdaptiveStrategyConfig::default()
    };
    let ppo_strategy = Box::new(create_adaptive_strategy_with_config(adaptive_config));
    engine.set_strategy(ppo_strategy).await.unwrap();

    let state = engine.get_state().await;
    assert!(!state.is_running);
}

#[tokio::test]
async fn test_tlob_strategy_integration() {
    let config = BacktestConfig::default();
    let mut engine = BacktestEngine::new(config).await.unwrap();

    // Set adaptive strategy with TLOB model
    let adaptive_config = AdaptiveStrategyConfig {
        active_models: vec!["TLOB".to_string()],
        ..AdaptiveStrategyConfig::default()
    };
    let tlob_strategy = Box::new(create_adaptive_strategy_with_config(adaptive_config));
    engine.set_strategy(tlob_strategy).await.unwrap();

    let state = engine.get_state().await;
    assert!(!state.is_running);
}

#[tokio::test]
async fn test_ensemble_strategy_integration() {
    let config = BacktestConfig::default();
    let mut engine = BacktestEngine::new(config).await.unwrap();

    // Set adaptive strategy with multiple ML models (ensemble)
    let adaptive_config = AdaptiveStrategyConfig {
        active_models: vec!["DQN".to_string(), "PPO".to_string(), "TLOB".to_string()],
        ..AdaptiveStrategyConfig::default()
    };
    let ensemble_strategy = Box::new(create_adaptive_strategy_with_config(adaptive_config));
    engine.set_strategy(ensemble_strategy).await.unwrap();

    let state = engine.get_state().await;
    assert!(!state.is_running);
    assert_eq!(state.portfolio_value, Decimal::ZERO); // Not yet initialized
}

#[tokio::test]
async fn test_adaptive_strategy_configuration() {
    // Create custom adaptive strategy configuration
    let config = AdaptiveStrategyConfig {
        active_models: vec!["DQN".to_string(), "PPO".to_string(), "TLOB".to_string()],
        min_confidence: 0.7,     // Higher confidence requirement
        max_position_size: 0.05, // 5% position size
        lookback_period: 20,
        model_update_frequency: 100,
        risk_settings: RiskSettings {
            max_drawdown: 0.15, // 15% max drawdown
            stop_loss: 0.05,
            take_profit: 0.10,
            kelly_fraction: 0.25,
        },
        feature_settings: FeatureSettings::default(),
    };

    let adaptive_strategy = create_adaptive_strategy_with_config(config.clone());

    // Test as a Strategy trait object to verify it implements the trait
    let strategy: Box<dyn backtesting::Strategy> = Box::new(adaptive_strategy);

    // Verify strategy has a name (strategy trait method)
    let strategy_name = strategy.name();
    assert!(
        !strategy_name.is_empty(),
        "Strategy should have a non-empty name"
    );
}
