use ashpd::desktop::settings::Settings;
use gio::Settings as GSettings;
use gtk4::prelude::SettingsExt;
use tokio::sync::OnceCell;

use crate::infrastructure::TokioRuntime;

pub const DEFAULT_DOCUMENT_FONT: &str = "Adwaita Sans 11";

#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum ClockFormat {
    F12H,
    F24H,
}

#[derive(Debug, Default)]
pub struct DesktopSettings {
    clock_format: OnceCell<ClockFormat>,
    document_font: OnceCell<String>,
}

impl DesktopSettings {
    pub fn init(&self) {
        let clock_format = self.clock_format.clone();
        let document_font = self.document_font.clone();

        TokioRuntime::spawn(async move {
            let clock_future = clock_format.get_or_init(Self::get_clock_format);
            let document_future = document_font.get_or_init(Self::get_document_font);

            let (_, _) = tokio::join!(clock_future, document_future);
        });
    }

    async fn get_document_font() -> String {
        if ashpd::is_sandboxed() {
            let Ok(settings) = Settings::new().await else {
                return DEFAULT_DOCUMENT_FONT.into();
            };
            settings
                .read::<String>("org.gnome.desktop.interface", "document-font-name")
                .await
                .unwrap_or(DEFAULT_DOCUMENT_FONT.into())
        } else {
            GSettings::new("org.gnome.desktop.interface")
                .string("document-font-name")
                .as_str()
                .into()
        }
    }

    async fn get_clock_format() -> ClockFormat {
        let clock_format = if ashpd::is_sandboxed() {
            let Ok(settings) = Settings::new().await else {
                return ClockFormat::F24H;
            };
            settings
                .read::<String>("org.gnome.desktop.interface", "clock-format")
                .await
                .unwrap_or("24h".into())
        } else {
            GSettings::new("org.gnome.desktop.interface")
                .string("clock-format")
                .as_str()
                .into()
        };

        match clock_format.as_str() {
            "12h" => ClockFormat::F12H,
            "24h" => ClockFormat::F24H,
            _ => ClockFormat::F24H,
        }
    }

    pub fn clock_format(&self) -> ClockFormat {
        self.clock_format.get().copied().unwrap_or(ClockFormat::F24H)
    }

    pub fn document_font(&self) -> String {
        self.document_font
            .get()
            .cloned()
            .unwrap_or(DEFAULT_DOCUMENT_FONT.into())
    }
}
