use serde::{Deserialize, Serialize};

#[derive(Clone, Copy, Debug, Deserialize, Hash, PartialEq, PartialOrd, Serialize)]
#[serde(from = "u8")]
#[repr(u8)]
pub enum MangaDexAtHome {
    Nope = 0,
    Normal = 1,
    EarlyAdopter = 2,
}

impl Default for MangaDexAtHome {
    fn default() -> Self {
        0u8.into()
    }
}

impl std::fmt::Display for MangaDexAtHome {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
        fmt.write_str(match self {
            Self::Nope => "Nope",
            Self::Normal => "Normal",
            Self::EarlyAdopter => "Early Adopter",
        })
    }
}

impl From<u8> for MangaDexAtHome {
    fn from(value: u8) -> Self {
        match value {
            0 => Self::Nope,
            1 => Self::Normal,
            2 => Self::EarlyAdopter,
            _ => Self::Nope,
        }
    }
}

impl From<u16> for MangaDexAtHome {
    fn from(value: u16) -> Self {
        match value {
            0 => Self::Nope,
            1 => Self::Normal,
            2 => Self::EarlyAdopter,
            _ => Self::Nope,
        }
    }
}

impl From<u32> for MangaDexAtHome {
    fn from(value: u32) -> Self {
        match value {
            0 => Self::Nope,
            1 => Self::Normal,
            2 => Self::EarlyAdopter,
            _ => Self::Nope,
        }
    }
}

impl From<u64> for MangaDexAtHome {
    fn from(value: u64) -> Self {
        match value {
            0 => Self::Nope,
            1 => Self::Normal,
            2 => Self::EarlyAdopter,
            _ => Self::Nope,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn mangadex_at_home_produces_nope_from_default() {
        let mangadex_at_home = MangaDexAtHome::default();
        assert_eq!(mangadex_at_home, MangaDexAtHome::Nope);
    }

    #[test]
    fn mangadex_at_home_produces_nope_from_0() {
        let mangadex_at_home = MangaDexAtHome::from(0u8);
        assert_eq!(mangadex_at_home, MangaDexAtHome::Nope);
    }

    #[test]
    fn mangadex_at_home_produces_nope_from_3() {
        let mangadex_at_home = MangaDexAtHome::from(21u8);
        assert_eq!(mangadex_at_home, MangaDexAtHome::Nope);
    }
}
