use crate::trend_value::TrendValue;

#[derive(Debug, Clone)]
pub struct TrendMetrics {
    pub short_term_val: TrendValue,
    pub long_term_val: TrendValue,
    pub macd: TrendValue,
    pub val: TrendValue,
    pub max_val: f64,
    pub min_val: f64,
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum CrossOverType {
    GoldenCross,
    DeadCross,
    None,
}

impl CrossOverType {
    pub fn to_numeric(&self) -> f64 {
        match self {
            CrossOverType::GoldenCross => 0.6,
            CrossOverType::DeadCross => 0.4,
            CrossOverType::None => 0.5,
        }
    }
}

impl TrendMetrics {
    pub fn new(short_period: usize, long_period: usize, trading_period: usize) -> Self {
        Self {
            short_term_val: TrendValue::new(short_period),
            long_term_val: TrendValue::new(long_period),
            val: TrendValue::new(trading_period),
            macd: TrendValue::new(trading_period),
            max_val: 0.0,
            min_val: u32::MAX as f64,
        }
    }

    pub fn update(&mut self, new_value: f64, short_value: f64, long_value: f64) {
        self.short_term_val.update_value(short_value);
        self.long_term_val.update_value(long_value);
        self.val.update_value(new_value);

        let ema_diff =
            self.short_term_val.current_ema().unwrap() - self.long_term_val.current_ema().unwrap();
        self.macd.update_value(ema_diff);

        self.max_val = self.max_val.max(new_value);
        self.min_val = self.min_val.min(new_value);
    }

    pub fn is_crossover(&mut self) -> Result<CrossOverType, ()> {
        let current_macd = self.macd.current_ema().ok_or(())?;
        let previous_macd = self.macd.previous_ema().ok_or(())?;
        let current_signal = self.macd.current_value().ok_or(())?;
        let previous_signal = self.macd.previous_value().ok_or(())?;

        let current_state = if current_signal > current_macd && previous_signal <= previous_macd {
            CrossOverType::GoldenCross
        } else if current_signal < current_macd && previous_signal >= previous_macd {
            CrossOverType::DeadCross
        } else {
            CrossOverType::None
        };

        Ok(current_state)
    }
}
