use std::sync::LazyLock;

use arc_swap::ArcSwap;

use super::prelude::*;

static LAST_MESSAGE: LazyLock<ArcSwap<Option<String>>> =
    LazyLock::new(|| ArcSwap::new(Default::default()));

async fn proxy() -> Option<Arc<ashpd::desktop::background::BackgroundProxy>> {
    static PROXY: smol::lock::Mutex<Option<Arc<ashpd::desktop::background::BackgroundProxy>>> =
        smol::lock::Mutex::new(None);

    let mut proxy = PROXY.lock().await;

    if let Some(proxy) = &*proxy {
        Some(proxy.clone())
    } else {
        let new_proxy = Arc::new(
            ashpd::desktop::background::BackgroundProxy::new()
                .await
                .ok()?,
        );
        *proxy = Some(new_proxy.clone());
        Some(new_proxy.clone())
    }
}

pub async fn background_activity_update() {
    let message = BORG_OPERATION.with(|operations| operations.load().summarize_operations());
    set_status_message(&message.unwrap_or(gettext("Idle"))).await;
}

pub async fn set_status_message(message: &str) {
    let ellipsized_message = crate::utils::ellipsize_end(message, 96);
    let new_message = Arc::new(Some(ellipsized_message.clone()));
    let last_message = LAST_MESSAGE.swap(new_message.clone());

    if *last_message != *new_message {
        tracing::debug!("New background status: {new_message:?}");

        if !*common::globals::APP_IS_SANDBOXED {
            return;
        }

        let options = ashpd::desktop::background::SetStatusOptions::default()
            .set_message(&ellipsized_message);
        if let Some(proxy) = proxy().await
            && let Err(err) = proxy.set_status(options).await
        {
            tracing::debug!("Error setting background status: {err:?}");
        }
    }
}
