use std::marker::PhantomData;

use crate::{
    BETA, GAMMA,
    drift::{ConstantDrift, Drift},
    gaussian::Gaussian,
    time::Time,
};

/// Static rating configuration: prior skill, performance noise `beta`, drift.
///
/// Renamed from `Player` in T2; `Rating` better describes the data
/// (a configuration) vs. a person (who's a `Competitor` with state).
#[derive(Clone, Copy, Debug)]
pub struct Rating<T: Time = i64, D: Drift<T> = ConstantDrift> {
    pub(crate) prior: Gaussian,
    pub(crate) beta: f64,
    pub(crate) drift: D,
    pub(crate) _time: PhantomData<T>,
}

impl<T: Time, D: Drift<T>> Rating<T, D> {
    pub fn new(prior: Gaussian, beta: f64, drift: D) -> Self {
        Self {
            prior,
            beta,
            drift,
            _time: PhantomData,
        }
    }

    pub(crate) fn performance(&self) -> Gaussian {
        self.prior.forget(self.beta.powi(2))
    }
}

impl Default for Rating<i64, ConstantDrift> {
    fn default() -> Self {
        Self {
            prior: Gaussian::default(),
            beta: BETA,
            drift: ConstantDrift(GAMMA),
            _time: PhantomData,
        }
    }
}
