use crate::trend_value::TrendValue;
use debot_utils::exponential_decay;
use lazy_static::lazy_static;
use std::env;

lazy_static! {
    static ref A_VALUE: f64 = {
        env::var("CROSSOVER_EFFECT_FACTOR")
            .unwrap_or_else(|_| "2.0".to_string())
            .parse::<f64>()
            .unwrap_or(1.0)
    };
}

#[derive(Debug, Clone)]
pub struct TrendMetrics {
    pub short_term_val: TrendValue,
    pub long_term_val: TrendValue,
    last_golden_cross: Option<i64>,
    last_death_cross: Option<i64>,
    cross_effective_duration_secs: i64,
}

impl TrendMetrics {
    pub fn new(
        short_period: usize,
        long_period: usize,
        cross_effective_duration_secs: i64,
    ) -> Self {
        Self {
            short_term_val: TrendValue::new(short_period),
            long_term_val: TrendValue::new(long_period),
            last_golden_cross: None,
            last_death_cross: None,
            cross_effective_duration_secs,
        }
    }

    pub fn crossover_effect(&mut self) -> f64 {
        let current_time = chrono::Utc::now().timestamp();
        let base_effect = 0.375;
        let mut effect = 0.0;

        let calculate_effect = |last_cross_time: i64, effect: f64| -> f64 {
            let elapsed = current_time - last_cross_time;
            if elapsed > self.cross_effective_duration_secs {
                return 0.0;
            }
            let a = *A_VALUE;
            effect
                * exponential_decay(
                    elapsed as f64 / self.cross_effective_duration_secs as f64,
                    a,
                )
        };

        if let Some(last_cross_time) = self.last_golden_cross {
            effect += calculate_effect(last_cross_time, base_effect);
        }

        if let Some(last_cross_time) = self.last_death_cross {
            effect -= calculate_effect(last_cross_time, base_effect);
        }

        // Short term crosses above long term
        if self.short_term_val.current_ema > self.long_term_val.current_ema
            && self.short_term_val.previous_ema <= self.long_term_val.previous_ema
        {
            self.last_golden_cross = Some(chrono::Utc::now().timestamp());
            effect += base_effect;
        }

        // Short term crosses below long term
        if self.short_term_val.current_ema < self.long_term_val.current_ema
            && self.short_term_val.previous_ema >= self.long_term_val.previous_ema
        {
            self.last_death_cross = Some(chrono::Utc::now().timestamp());
            effect -= base_effect;
        }

        effect
    }
}
