use gio::prelude::*;
use adw::prelude::*;
use relm4::prelude::*;

pub struct Preferences {
    settings: gio::Settings,
}

#[cfg(feature = "smart-summary")]
#[allow(dead_code)]
struct LanguageModelPreferencesWidgets {
    page: adw::PreferencesPage,

    general_group: adw::PreferencesGroup,
    llm_endpoint: adw::EntryRow,
    smart_summary_show_warning: adw::SwitchRow,
    
    smart_summary_group: adw::PreferencesGroup,
    smart_summary_model: adw::EntryRow,
    smart_summary_system_prompt: adw::EntryRow,
    smart_summary_prompt_prefix: adw::EntryRow,
    smart_summary_prompt_suffix: adw::EntryRow,
}

#[cfg(feature = "smart-summary")]
impl LanguageModelPreferencesWidgets {
    fn new(settings: &gio::Settings) -> Self {
        use gettextrs::*;

        let page = adw::PreferencesPage::builder()
            .title(gettext("Language Models"))
            .description(gettext("Settings for the language model integrations."))
            .icon_name("brain-augemnted") // sic!
            .build();

        let general_group = adw::PreferencesGroup::builder()
            .title(gettext("General"))
            .build();
        let llm_endpoint = adw::EntryRow::new();
        let smart_summary_show_warning = adw::SwitchRow::new();
        general_group.add(&llm_endpoint);
        general_group.add(&smart_summary_show_warning);
        page.add(&general_group);

        let smart_summary_group = adw::PreferencesGroup::builder()
            .title(gettext("Smart Summary"))
            .build();
        let smart_summary_model = adw::EntryRow::new();
        let smart_summary_system_prompt = adw::EntryRow::new();
        let smart_summary_prompt_prefix = adw::EntryRow::new();
        let smart_summary_prompt_suffix = adw::EntryRow::new();
        smart_summary_group.add(&smart_summary_model);
        smart_summary_group.add(&smart_summary_system_prompt);
        smart_summary_group.add(&smart_summary_prompt_prefix);
        smart_summary_group.add(&smart_summary_prompt_suffix);
        page.add(&smart_summary_group);

        let widgets = Self {
            page,

            general_group,
            llm_endpoint,
            smart_summary_show_warning,

            smart_summary_group,
            smart_summary_model,
            smart_summary_system_prompt,
            smart_summary_prompt_prefix,
            smart_summary_prompt_suffix
        };

        let schema = settings.settings_schema().unwrap();

        for (row, key, property) in [
            (widgets.llm_endpoint.upcast_ref::<adw::PreferencesRow>(), "llm-endpoint", "text"),
            (widgets.smart_summary_show_warning.upcast_ref::<_>(), "smart-summary-show-warning", "active"),
            (widgets.smart_summary_model.upcast_ref::<_>(), "smart-summary-model", "text"),
            (widgets.smart_summary_system_prompt.upcast_ref::<_>(), "smart-summary-system-prompt", "text"),
            (widgets.smart_summary_prompt_prefix.upcast_ref::<_>(), "smart-summary-prompt-prefix", "text"),
            (widgets.smart_summary_prompt_suffix.upcast_ref::<_>(), "smart-summary-prompt-suffix", "text"),
        ] {
            settings.bind(key, row, property)
                .get()
                .set()
                .build();
            row.set_title(&gettext(schema.key(key).summary().unwrap()));
        }

        widgets
    }
}

pub struct PreferencesWidgets {
    #[cfg(feature = "smart-summary")]
    llm: LanguageModelPreferencesWidgets
}

impl Component for Preferences {
    type CommandOutput = ();
    type Input = Option<gtk::Widget>;
    type Output = ();
    type Init = ();
    type Root = adw::PreferencesDialog;
    type Widgets = PreferencesWidgets;

    fn init_root() -> Self::Root {
        adw::PreferencesDialog::new()
    }

    fn init(
        _: Self::Init,
        root: Self::Root,
        _sender: ComponentSender<Self>,
    ) -> ComponentParts<Self> {
        let model = Self {
            settings: gio::Settings::new(crate::APPLICATION_ID),
        };

        model.settings.delay();

        let widgets = PreferencesWidgets {
            #[cfg(feature = "smart-summary")]
            llm: LanguageModelPreferencesWidgets::new(&model.settings),
        };
        #[cfg(feature = "smart-summary")]
        root.add(&widgets.llm.page);

        root.connect_closed(glib::clone!(
            #[strong(rename_to = settings)]
            model.settings,
            move |_| {
                settings.apply()
            }
        ));

        ComponentParts { model, widgets }
    }

    fn update(&mut self, msg: Self::Input, _sender: ComponentSender<Self>, root: &Self::Root) {
        root.present(msg.as_ref());
    }

    fn shutdown(&mut self, _: &mut Self::Widgets, _: relm4::Sender<()>) {
        self.settings.apply()
    }
}