use configparser::ini::WriteOptions;
use palette::Srgba;
use palette::rgb::Rgba;
use thiserror::Error;

use crate::Theme;

/// Module for outputting the Cosmic gtk4 theme type as CSS
pub mod gtk4_output;

/// Module for configuring qt5ct and qt6ct to use our qt theme
pub mod qt56ct_output;
/// Module for outputting the Cosmic qt theme type as kdeglobals
pub mod qt_output;

pub mod vs_code;

#[derive(Error, Debug)]
pub enum OutputError {
    #[error("IO Error: {0}")]
    Io(std::io::Error),
    #[error("Missing config directory")]
    MissingConfigDir,
    #[error("Missing data directory")]
    MissingDataDir,
    #[error("Serde Error: {0}")]
    Serde(#[from] serde_json::Error),
    #[error("Ini Error: {0}")]
    Ini(String),
}

impl Theme {
    #[inline]
    /// Apply COSMIC theme exports for GTK and Qt applications.
    pub fn apply_exports(&self) -> Result<(), OutputError> {
        let gtk_res = Theme::apply_gtk(self.is_dark);
        let qt_res = Theme::apply_qt(self.is_dark);
        let qt56ct_res = Theme::apply_qt56ct(self.is_dark);
        gtk_res?;
        qt_res?;
        qt56ct_res?;
        Ok(())
    }

    #[inline]
    /// Write COSMIC theme exports for GTK and Qt applications.
    pub fn write_exports(&self) -> Result<(), OutputError> {
        let gtk_res = self.write_gtk4();
        let qt_res = self.write_qt();
        let qt56ct_res = self.write_qt56ct();
        gtk_res?;
        qt_res?;
        qt56ct_res?;
        Ok(())
    }

    #[inline]
    /// Un-export GTK and Qt theme configurations applied by us.
    pub fn reset_exports() -> Result<(), OutputError> {
        let gtk_res = Theme::reset_gtk();
        let qt_res = Theme::reset_qt();
        let qt56ct_res = Theme::reset_qt56ct();
        gtk_res?;
        qt_res?;
        qt56ct_res?;
        Ok(())
    }
}

pub fn to_hex(c: Srgba) -> String {
    let c_u8: Rgba<palette::encoding::Srgb, u8> = c.into_format();
    format!(
        "{:02x}{:02x}{:02x}{:02x}",
        c_u8.red, c_u8.green, c_u8.blue, c_u8.alpha
    )
}

pub fn to_rgba(c: Srgba) -> String {
    let c_u8: Rgba<palette::encoding::Srgb, u8> = c.into_format();
    format!(
        "rgba({}, {}, {}, {:1.2})",
        c_u8.red, c_u8.green, c_u8.blue, c.alpha
    )
}

pub fn qt_settings_ini_style() -> WriteOptions {
    let mut write_options = WriteOptions::default();
    write_options.blank_lines_between_sections = 1;
    write_options
}
