use gtk::gdk;

#[cfg(feature = "serde")]
use serde::Deserialize;

/// Represents a [`ThemeColor`] variant.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThemeColorVariant {
    Light,
    Dark,
}

impl ThemeColorVariant {
    /// Interrogates libadwaita to get the current preferred
    /// [`ThemeColorVariant`].
    pub fn current(display: &gdk::Display) -> Self {
        if adw::StyleManager::for_display(display).is_dark() {
            Self::Dark
        } else {
            Self::Light
        }
    }
}

/// Light/Dark aware color. Provide both color variants to offer seamless
/// compatibility between dark and light theme preference. The value of the
/// colors should be a CSS compatible color value.
///
/// ## Example
///
/// ```
/// use delicious_adwaita::color::{ThemeColor, ThemeColorVariant};
///
/// let my_accent = ThemeColor::new("#ff0000", "#aa0000");
/// let my_foreground = ThemeColor::new("rgba(0, 0, 0, .8)", "rgba(255, 255, 255, .8)");
///
/// assert_eq!(my_accent.get(ThemeColorVariant::Light), "#ff0000");
/// assert_eq!(my_foreground.get(ThemeColorVariant::Dark), "rgba(255, 255, 255, .8)");
/// ```
#[cfg_attr(feature = "serde", derive(Deserialize))]
#[derive(Debug, Clone)]
pub struct ThemeColor {
    light: String,
    dark: String,
}

impl ThemeColor {
    /// Creates a new [`ThemeColor`]. Parameters `light` and `dark` should be
    /// valid CSS compatible color values.
    pub fn new(light: &str, dark: &str) -> Self {
        Self {
            light: light.into(),
            dark: dark.into(),
        }
    }

    /// Get the specific color value given a [`ThemeColorVariant`].
    ///
    /// The fields `light` and `dark` in [`ThemeColor`] are private explicitly
    /// because it doesn't make sense to get an arbitrary color value, it's
    /// only meaningful given a context on which variant is needed.
    ///
    /// ## Example
    ///
    /// ```no_run
    /// use gtk::gdk;
    /// use delicious_adwaita::color::{ThemeColor, ThemeColorVariant};
    ///
    /// let my_accent = ThemeColor::new("#ff0000", "#aa0000");
    /// // gdk::Display::default() returns None if gtk is not initialized
    /// my_accent.get(ThemeColorVariant::current(&gdk::Display::default().unwrap()));
    /// ```
    pub fn get(&self, variant: ThemeColorVariant) -> String {
        match variant {
            ThemeColorVariant::Light => &self.light,
            ThemeColorVariant::Dark => &self.dark,
        }
        .clone()
    }
}
