use serde::{Deserialize, Serialize};

///
/// Possible ratings for a [Site]
///
#[derive(Serialize, Deserialize, Debug)]
pub enum Standing {
    Good,
    Bad,
    Neutral,
}

impl std::fmt::Display for Standing {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Standing::Good => write!(f, "good"),
            Standing::Bad => write!(f, "bad"),
            Standing::Neutral => write!(f, "neutral"),
        }
    }
}

impl TryFrom<String> for Standing {
    type Error = &'static str;
    fn try_from(value: String) -> Result<Self, Self::Error> {
        match value.to_lowercase().as_str() {
            "good" => Ok(Standing::Good),
            "bad" => Ok(Standing::Bad),
            "neutral" => Ok(Standing::Neutral),
            _ => Err("Not a valid standing value!"),
        }
    }
}

impl From<i64> for Standing {
    fn from(n: i64) -> Self {
        if n > 0 {
            Standing::Good
        } else if n < 0 {
            Standing::Bad
        } else {
            Standing::Neutral
        }
    }
}

///
/// What a [Ring] server sends as a standing result
///
#[derive(Serialize, Deserialize, Debug)]
pub struct StandingResult {
    pub standing: Standing,
    pub vote_split: VoteSplit,
    pub descriptions: Vec<String>,
}

///
/// Represents the respective counts of
/// good, bad, and neutral standing
///
#[derive(Serialize, Deserialize, Debug)]
pub struct VoteSplit {
    pub good: usize,
    pub bad: usize,
    pub neutral: usize,
}
