use std::path::PathBuf;

use gettextrs::gettext;
use gtk::{glib, prelude::*, subclass::prelude::*};

mod imp {
    use glib::{once_cell::sync::Lazy, subclass::Signal};

    use super::*;

    #[derive(Debug, Default, gtk::CompositeTemplate)]
    #[template(resource = "/org/gnome/design/SymbolicPreview/export_popover.ui")]
    pub struct ExportPopover {
        #[template_child]
        pub(super) path_entry: TemplateChild<gtk::Entry>,
        #[template_child]
        pub(super) export_btn: TemplateChild<gtk::Button>,
    }

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

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

            klass.install_action_async(
                "export-project.select-location",
                None,
                |popover, _, _| async move {
                    popover.select_destination().await;
                },
            );
        }

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

    impl ObjectImpl for ExportPopover {
        fn signals() -> &'static [Signal] {
            static SIGNALS: Lazy<Vec<Signal>> = Lazy::new(|| {
                vec![Signal::builder("exported")
                    .param_types([String::static_type()])
                    .build()]
            });
            SIGNALS.as_ref()
        }
    }
    impl WidgetImpl for ExportPopover {}
    impl PopoverImpl for ExportPopover {}
}

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

#[gtk::template_callbacks]
impl ExportPopover {
    #[template_callback]
    fn on_export_btn_clicked(&self, _btn: gtk::Button) {
        let export_dest = self.imp().path_entry.text();
        self.emit_by_name::<()>("exported", &[&export_dest]);

        self.popdown();
    }

    #[template_callback]
    fn on_entry_changed(&self, entry: gtk::Entry) {
        let export_dest = PathBuf::from(entry.text());
        self.imp().export_btn.set_sensitive(export_dest.exists());
    }

    async fn select_destination(&self) {
        self.popdown();
        let parent = self.root().and_downcast::<gtk::Window>().unwrap();
        let file_dialog = gtk::FileDialog::new();
        if let Ok(destination) = file_dialog.select_folder_future(Some(&parent)).await {
            self.imp()
                .path_entry
                .set_text(destination.path().unwrap().to_str().unwrap());
        }
        self.popup();
    }
}
