use gtk::{
    gio,
    glib::{self, IsA},
    prelude::*,
    subclass::prelude::*,
};

use super::item::RecentItemRow;

mod imp {
    use super::*;

    #[derive(Debug, Default, gtk::CompositeTemplate)]
    #[template(resource = "/org/gnome/design/SymbolicPreview/recent_popover.ui")]
    pub struct RecentPopover {
        #[template_child]
        pub(super) items_listbox: TemplateChild<gtk::ListBox>,
    }

    #[glib::object_subclass]
    impl ObjectSubclass for RecentPopover {
        const NAME: &'static str = "RecentPopover";
        type Type = super::RecentPopover;
        type ParentType = gtk::Popover;

        fn class_init(klass: &mut Self::Class) {
            klass.bind_template();
        }

        fn instance_init(obj: &glib::subclass::InitializingObject<Self>) {
            obj.init_template();
        }
    }

    impl ObjectImpl for RecentPopover {}
    impl WidgetImpl for RecentPopover {}
    impl PopoverImpl for RecentPopover {}
}

glib::wrapper! {
    pub struct RecentPopover(ObjectSubclass<imp::RecentPopover>)
        @extends gtk::Widget, gtk::Popover;
}

impl RecentPopover {
    pub fn set_model<M: IsA<gio::ListModel>>(&self, history_model: &M) {
        self.imp()
            .items_listbox
            .bind_model(Some(history_model), move |item| {
                let item: std::path::PathBuf = item
                    .downcast_ref::<gtk::StringObject>()
                    .unwrap()
                    .string()
                    .as_str()
                    .into();
                let row = RecentItemRow::new(item);
                row.upcast::<gtk::Widget>()
            });
    }
}
