mod analyze;
mod candle;
mod pid_controller;
mod trade_action;
mod trend_metrics;
mod trend_value;

pub use analyze::{InagoThresholds, MarketData, VolumeBarMode};
pub use pid_controller::{AdaptivePidController, PidController, PidThresholds, SetpointMode};
pub use trade_action::TradeAction;
pub use trade_action::TradeDetail;

#[cfg(not(any(feature = "classification", feature = "regression")))]
compile_error!("Either 'classification' or 'regression' feature must be enabled");

#[cfg(test)]
mod tests {
    use super::*;
    use debot_db::{TradingStrategy, TrendType};
    use rust_decimal::Decimal;

    #[test]
    fn test_random_inago_debug_logging() {
        env_logger::init();
        log::debug!("Testing Random Inago debug logging");

        let mut market_data = MarketData::new(
            "TEST".to_string(),
            10,
            50,
            20,
            10,
            1000,
            None,
            false,
            0.5,
            VolumeBarMode::Always,
            Decimal::ONE,
        );

        // Add sufficient price data for indicators to calculate (need at least 50+ for long period)
        for i in 0..100 {
            // Create more realistic price variations
            let base_price = 100.0;
            let price_variation = (i as f64 * 0.1).sin() * 5.0; // Price oscillates ±5
            let trend = i as f64 * 0.01; // Slight upward trend
            let price = base_price + trend + price_variation;

            market_data.add_price(
                Some(Decimal::try_from(price).unwrap()),
                Some(1600000000 + i * 60),
                Some(Decimal::new(1000 + i, 0)), // Varying volume
                Some((10 + i % 5) as u64),
                None,
                None,
                None,
            );
        }

        log::debug!("Added price data, prices count: {}", 100);

        let thresholds = InagoThresholds::default();
        let actions = market_data.is_signaled(
            TradingStrategy::RandomInago(TrendType::Up),
            0,
            Decimal::new(1, 2), // 0.01
            Decimal::new(1, 2), // 0.01
            &debot_db::SampleTerm::ShortTerm,
            None,
            1,
            Decimal::new(2, 0),       // 2.0
            Some(Decimal::new(1, 4)), // 0.0001
            0,
            Decimal::new(1, 2), // 0.01
            Some(thresholds),
            None, // pid_thresholds
        );

        log::info!("Test completed with {} actions", actions.len());
    }

    #[test]
    fn test_pid_controller_strategy() {
        env_logger::init();
        log::debug!("Testing PID Controller strategy");

        let mut market_data = MarketData::new(
            "TEST_PID".to_string(),
            10,
            50,
            20,
            10,
            1000,
            None,
            false,
            0.5,
            VolumeBarMode::Always,
            Decimal::ONE,
        );

        // Add price data with a clear trend
        for i in 0..100 {
            let base_price = 100.0;
            let trend = i as f64 * 0.05; // Strong upward trend
            let noise = (i as f64 * 0.2).sin() * 2.0; // Some noise
            let price = base_price + trend + noise;

            market_data.add_price(
                Some(Decimal::try_from(price).unwrap()),
                Some(1600000000 + i * 60),
                Some(Decimal::new(1000 + i, 0)),
                Some((10 + i % 5) as u64),
                None,
                None,
                None,
            );
        }

        log::debug!("Added price data for PID test, prices count: {}", 100);

        // Test PID controller strategy
        let pid_thresholds = PidThresholds::default();
        let actions = market_data.is_signaled(
            TradingStrategy::PidController(TrendType::Up),
            0,
            Decimal::new(1, 2), // 0.01
            Decimal::new(1, 2), // 0.01
            &debot_db::SampleTerm::ShortTerm,
            None,
            1,
            Decimal::new(2, 0),       // 2.0
            Some(Decimal::new(1, 4)), // 0.0001
            0,
            Decimal::new(1, 2), // 0.01
            None,               // inago_thresholds
            Some(pid_thresholds),
        );

        log::info!("PID test completed with {} actions", actions.len());

        // Test Random PID controller strategy
        let pid_thresholds = PidThresholds::default();
        let actions = market_data.is_signaled(
            TradingStrategy::RandomPidController(TrendType::Any),
            0,
            Decimal::new(1, 2),
            Decimal::new(1, 2),
            &debot_db::SampleTerm::ShortTerm,
            None,
            1,
            Decimal::new(2, 0),
            Some(Decimal::new(1, 4)),
            0,
            Decimal::new(1, 2),
            None,
            Some(pid_thresholds),
        );

        log::info!("Random PID test completed with {} actions", actions.len());

        // Check PID status
        if let Some((kp, ki, kd)) = market_data.get_pid_status() {
            log::info!("PID gains - Kp: {}, Ki: {}, Kd: {}", kp, ki, kd);
        }
    }
}
