use serde::{Deserialize, Serialize};

#[derive(Clone, Copy, Debug, Deserialize, Hash, PartialEq, PartialOrd, Serialize)]
#[serde(from = "u8")]
#[repr(u8)]
pub enum SiteTheme {
    Dark = 2,
    LightBronze = 3,
    DarkBronze = 4,
    LightSlate = 5,
    DarkSlate = 6,
    Abyss = 7,
    #[serde(other)]
    Light = 1,
}

impl Default for SiteTheme {
    fn default() -> Self {
        1u8.into()
    }
}

impl std::fmt::Display for SiteTheme {
    fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
        fmt.write_str(match self {
            Self::Light => "Light",
            Self::Dark => "Dark",
            Self::LightBronze => "Light-Bronze",
            Self::DarkBronze => "Dark-Bronze",
            Self::LightSlate => "Light-Slate",
            Self::DarkSlate => "Dark-Slate",
            Self::Abyss => "Abyss",
        })
    }
}

impl From<u8> for SiteTheme {
    fn from(value: u8) -> Self {
        match value {
            1 => Self::Light,
            2 => Self::Dark,
            3 => Self::LightBronze,
            4 => Self::DarkBronze,
            5 => Self::LightSlate,
            6 => Self::DarkSlate,
            7 => Self::Abyss,
            _ => Self::Light,
        }
    }
}

impl From<u16> for SiteTheme {
    fn from(value: u16) -> Self {
        match value {
            1 => Self::Light,
            2 => Self::Dark,
            3 => Self::LightBronze,
            4 => Self::DarkBronze,
            5 => Self::LightSlate,
            6 => Self::DarkSlate,
            7 => Self::Abyss,
            _ => Self::Light,
        }
    }
}

impl From<u32> for SiteTheme {
    fn from(value: u32) -> Self {
        match value {
            1 => Self::Light,
            2 => Self::Dark,
            3 => Self::LightBronze,
            4 => Self::DarkBronze,
            5 => Self::LightSlate,
            6 => Self::DarkSlate,
            7 => Self::Abyss,
            _ => Self::Light,
        }
    }
}

impl From<u64> for SiteTheme {
    fn from(value: u64) -> Self {
        match value {
            1 => Self::Light,
            2 => Self::Dark,
            3 => Self::LightBronze,
            4 => Self::DarkBronze,
            5 => Self::LightSlate,
            6 => Self::DarkSlate,
            7 => Self::Abyss,
            _ => Self::Light,
        }
    }
}

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

    #[test]
    fn site_theme_produces_light_from_default() {
        let site_theme = SiteTheme::default();
        assert_eq!(site_theme, SiteTheme::Light);
    }

    #[test]
    fn site_theme_produces_light_from_0() {
        let site_theme = SiteTheme::from(0u8);
        assert_eq!(site_theme, SiteTheme::Light);
    }

    #[test]
    fn site_theme_produces_dark_from_2() {
        let site_theme = SiteTheme::from(2u8);
        assert_eq!(site_theme, SiteTheme::Dark);
    }
}
