#![allow(
    clippy::assertions_on_constants,
    clippy::assertions_on_result_states,
    clippy::clone_on_copy,
    clippy::decimal_literal_representation,
    clippy::doc_markdown,
    clippy::empty_line_after_doc_comments,
    clippy::field_reassign_with_default,
    clippy::get_unwrap,
    clippy::identity_op,
    clippy::inconsistent_digit_grouping,
    clippy::indexing_slicing,
    clippy::integer_division,
    clippy::len_zero,
    clippy::let_underscore_must_use,
    clippy::manual_div_ceil,
    clippy::manual_let_else,
    clippy::manual_range_contains,
    clippy::modulo_arithmetic,
    clippy::needless_range_loop,
    clippy::non_ascii_literal,
    clippy::redundant_clone,
    clippy::shadow_reuse,
    clippy::shadow_same,
    clippy::shadow_unrelated,
    clippy::single_match_else,
    clippy::str_to_string,
    clippy::string_slice,
    clippy::tests_outside_test_module,
    clippy::too_many_lines,
    clippy::unnecessary_wraps,
    clippy::unseparated_literal_suffix,
    clippy::use_debug,
    clippy::useless_vec,
    clippy::wildcard_enum_match_arm,
    clippy::else_if_without_else,
    clippy::expect_used,
    clippy::missing_const_for_fn,
    clippy::similar_names,
    clippy::type_complexity,
    clippy::collapsible_else_if,
    clippy::doc_lazy_continuation,
    clippy::items_after_test_module,
    clippy::map_clone,
    clippy::multiple_unsafe_ops_per_block,
    clippy::unwrap_or_default,
    clippy::assign_op_pattern,
    clippy::needless_borrow,
    clippy::println_empty_string,
    clippy::unnecessary_cast,
    clippy::used_underscore_binding,
    clippy::create_dir,
    clippy::implicit_saturating_sub,
    clippy::exit,
    clippy::expect_fun_call,
    clippy::too_many_arguments,
    clippy::unnecessary_map_or,
    clippy::unwrap_used,
    dead_code,
    unused_imports,
    unused_variables,
    clippy::cloned_ref_to_slice_refs,
    clippy::neg_multiply,
    clippy::while_let_loop,
    clippy::bool_assert_comparison,
    clippy::excessive_precision,
    clippy::trivially_copy_pass_by_ref,
    clippy::op_ref,
    clippy::redundant_closure,
    clippy::unnecessary_lazy_evaluations,
    clippy::if_then_some_else_none,
    clippy::unnecessary_to_owned,
    clippy::single_component_path_imports,
)]
#[cfg(test)]
mod hyperopt_price_extraction_tests {
    use approx::assert_relative_eq;

    /// Helper function to simulate the price extraction logic in hyperopt
    /// This mirrors the logic in ml/src/hyperopt/adapters/dqn.rs around line 1657
    fn extract_close_price_for_hyperopt(target: &[f64], feature_vec: &[f64]) -> f64 {
        if target.len() >= 4 {
            // NEW: Use target[2] (raw close price) when available
            target[2]
        } else if target.len() >= 2 {
            // FALLBACK: Use target[0] for backward compatibility
            target[0]
        } else {
            // LAST RESORT: Use feature_vec[3]
            feature_vec[3]
        }
    }

    #[test]
    fn test_hyperopt_uses_raw_prices_not_preprocessed() {
        // Given: Target vector with both preprocessed and raw prices
        // Layout: [preprocessed_close, preprocessed_next, raw_close, raw_next]
        let target = vec![
            -0.35,    // target[0] = preprocessed close (z-score)
            -0.40,    // target[1] = preprocessed next (z-score)
            5123.50,  // target[2] = RAW close price ✅ CORRECT
            5125.00,  // target[3] = RAW next price ✅
        ];
        let feature_vec = vec![0.0, 0.0, 0.0, 0.0];

        // When: Extract close price for hyperopt P&L calculation
        let close_price = extract_close_price_for_hyperopt(&target, &feature_vec);

        // Then: Should use RAW price (target[2]), NOT preprocessed (target[0])
        assert_relative_eq!(close_price, 5123.50, epsilon = 1e-6);
        assert_ne!(close_price, -0.35); // Verify NOT using preprocessed

        // Sanity check: Raw prices should be in reasonable range (ES futures: 4000-6000)
        assert!(close_price > 1000.0 && close_price < 10000.0);
    }

    #[test]
    fn test_hyperopt_backward_compatibility_len2() {
        // Given: Old target vector with only 2 elements (no raw prices)
        // This is the format before Wave 16M preprocessing changes
        let target_old = vec![-0.35, -0.40];
        let feature_vec = vec![0.0, 0.0, 0.0, 5000.0];

        // When: Extract close price
        let close_price = extract_close_price_for_hyperopt(&target_old, &feature_vec);

        // Then: Should fall back to target[0]
        assert_relative_eq!(close_price, -0.35, epsilon = 1e-6);
    }

    #[test]
    fn test_hyperopt_backward_compatibility_len1() {
        // Given: Extremely old target vector with only 1 element
        let target_old = vec![5100.0];
        let feature_vec = vec![0.0, 0.0, 0.0, 5000.0];

        // When: Extract close price
        let close_price = extract_close_price_for_hyperopt(&target_old, &feature_vec);

        // Then: Should fall back to feature_vec[3]
        assert_relative_eq!(close_price, 5000.0, epsilon = 1e-6);
    }

    #[test]
    fn test_hyperopt_realistic_es_futures_prices() {
        // Given: Realistic ES futures prices from actual trading data
        let test_cases = vec![
            (vec![-1.2, -0.8, 4523.75, 4525.50], 4523.75),  // Typical ES price
            (vec![0.5, 0.3, 5234.25, 5235.00], 5234.25),     // Higher ES price
            (vec![-2.1, -1.9, 4012.50, 4015.00], 4012.50),   // Lower ES price
        ];

        let feature_vec = vec![0.0, 0.0, 0.0, 0.0];

        for (target, expected_price) in test_cases {
            let close_price = extract_close_price_for_hyperopt(&target, &feature_vec);
            assert_relative_eq!(close_price, expected_price, epsilon = 1e-6);

            // Verify we're NOT using preprocessed values
            assert_ne!(close_price, target[0]);
        }
    }

    #[test]
    fn test_hyperopt_price_extraction_error_magnitude() {
        // Given: Example showing the 631% error from using wrong index
        let target = vec![
            -0.35,    // Preprocessed: z-score
            -0.40,    // Preprocessed: z-score
            5123.50,  // RAW: actual price
            5125.00,  // RAW: actual price
        ];
        let feature_vec = vec![0.0, 0.0, 0.0, 0.0];

        let correct_price = extract_close_price_for_hyperopt(&target, &feature_vec);
        let wrong_price = target[0]; // What we were using before (BUG)

        // Calculate error magnitude
        let error_magnitude = ((correct_price - wrong_price).abs() / correct_price) * 100.0;

        // Then: Error should be massive (>100%) when using wrong index
        assert!(error_magnitude > 100.0);

        // Verify correct extraction
        assert_relative_eq!(correct_price, 5123.50, epsilon = 1e-6);
    }
}
