use std::cell::Cell;

use glib::object::ObjectExt;
use glib::subclass::prelude::{ObjectSubclass, *};
use glib::Properties;
use transmission_client::StatsDetails;

mod imp {
    use super::*;

    #[derive(Debug, Default, Properties)]
    #[properties(wrapper_type = super::TrSessionStatsDetails)]
    pub struct TrSessionStatsDetails {
        #[property(get)]
        pub seconds_active: Cell<i64>,
        #[property(get)]
        pub downloaded_bytes: Cell<i64>,
        #[property(get)]
        pub uploaded_bytes: Cell<i64>,
        #[property(get)]
        pub files_added: Cell<i64>,
        #[property(get)]
        pub session_count: Cell<i64>,
    }

    #[glib::object_subclass]
    impl ObjectSubclass for TrSessionStatsDetails {
        const NAME: &'static str = "TrSessionStatsDetails";
        type ParentType = glib::Object;
        type Type = super::TrSessionStatsDetails;
    }

    #[glib::derived_properties]
    impl ObjectImpl for TrSessionStatsDetails {}
}

glib::wrapper! {
    pub struct TrSessionStatsDetails(ObjectSubclass<imp::TrSessionStatsDetails>);
}

impl TrSessionStatsDetails {
    pub(crate) fn refresh_values(&self, rpc_details: StatsDetails) {
        let imp = self.imp();

        // seconds_active
        if imp.seconds_active.get() != rpc_details.seconds_active {
            imp.seconds_active.set(rpc_details.seconds_active);
            self.notify_seconds_active();
        }

        // downloaded_bytes
        if imp.downloaded_bytes.get() != rpc_details.downloaded_bytes {
            imp.downloaded_bytes.set(rpc_details.downloaded_bytes);
            self.notify_downloaded_bytes();
        }

        // uploaded_bytes
        if imp.uploaded_bytes.get() != rpc_details.uploaded_bytes {
            imp.uploaded_bytes.set(rpc_details.uploaded_bytes);
            self.notify_uploaded_bytes();
        }

        // files_added
        if imp.files_added.get() != rpc_details.files_added {
            imp.files_added.set(rpc_details.files_added);
            self.notify_files_added();
        }

        // session_count
        if imp.session_count.get() != rpc_details.session_count {
            imp.session_count.set(rpc_details.session_count);
            self.notify_session_count();
        }
    }
}

impl Default for TrSessionStatsDetails {
    fn default() -> Self {
        glib::Object::new()
    }
}
