#[derive(Debug, Clone)]
pub struct TrendValue {
    pub current_value: f64,
    pub previous_value: f64,
    pub previous_values: Vec<f64>,
    pub current_trend: f64,
    pub previous_trend: f64,
    pub period: usize,
}

pub trait ValueChange {
    fn update_value(&mut self, new_val: f64);
    fn previous_average(&self) -> Option<f64>;
}

impl TrendValue {
    pub fn new(period: usize) -> Self {
        TrendValue {
            current_value: 0.0,
            previous_value: 0.0,
            previous_values: vec![],
            current_trend: 0.0,
            previous_trend: 0.0,
            period,
        }
    }

    fn trend(&self) -> f64 {
        match self.previous_average() {
            Some(avg) => (self.current_value - avg) / avg,
            None => 0.0,
        }
    }
}

impl ValueChange for TrendValue {
    fn update_value(&mut self, new_val: f64) {
        if self.previous_values.len() >= self.period {
            self.previous_values.remove(0);
        }
        self.previous_values.push(self.current_value);
        self.previous_value = self.current_value;
        self.current_value = new_val;
        self.previous_trend = self.current_trend;
        self.current_trend = self.trend();
    }

    fn previous_average(&self) -> Option<f64> {
        if self.previous_values.is_empty() {
            return None;
        }

        let sum: f64 = self.previous_values.iter().sum();
        Some(sum / (self.previous_values.len() as f64))
    }
}
