// SPDX-License-Identifier: GPL-3.0-or-later

use adw::subclass::prelude::*;
use adw::prelude::PreferencesGroupExt;
use gtk::prelude::*;
use gtk::glib;

use gettextrs::gettext;

use crate::config::PROFILE;

mod imp {
    use super::*;

    #[derive(Debug, gtk::CompositeTemplate)]
    #[template(resource = "/net/ffkkinos/Wildcard/ui/quick_reference_dialog.ui")]
    pub struct QuickReferenceDialog {
        #[template_child]
        pub common_preferences_group : TemplateChild<adw::PreferencesGroup>,
        #[template_child]
        pub anchors_preferences_group : TemplateChild<adw::PreferencesGroup>,
        #[template_child]
        pub quantifiers_preferences_group : TemplateChild<adw::PreferencesGroup>,
    }

    impl Default for QuickReferenceDialog {
        fn default() -> Self {
            Self {
                common_preferences_group: TemplateChild::default(),
                anchors_preferences_group: TemplateChild::default(),
                quantifiers_preferences_group: TemplateChild::default(),
            }
        }
    }

    #[glib::object_subclass]
    impl ObjectSubclass for QuickReferenceDialog {
        const NAME: &'static str = "QuickReferenceDialog";
        type Type = super::QuickReferenceDialog;
        type ParentType = adw::Dialog;

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

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

    impl ObjectImpl for QuickReferenceDialog {
        fn constructed(&self) {
            self.parent_constructed();
            let obj = self.obj();

            // Devel profile
            if PROFILE == "Devel" {
                obj.add_css_class("devel");
            }

            obj.load_common_group();
            obj.load_anchors_group();
            obj.load_quantifiers_group();
        }
    }

    impl WidgetImpl for QuickReferenceDialog {}
    impl AdwDialogImpl for QuickReferenceDialog {}
}

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

impl QuickReferenceDialog {
    #[allow(clippy::new_without_default)]
    pub fn new() -> Self {
        glib::Object::builder().build()
    }

    pub fn load_common_group(&self) {
        let examples = vec![
            self.new_example_row(
                &gettext("Matches either an a, b, or c character"),
                "[abc]",
                "aa bb ccc"
            ),
            self.new_example_row(
                &gettext("Matches everything expect an a, b, or c character"),
                "[^abc]",
                "aa bb cc dd ee ff"
            ),
            self.new_example_row(
                &gettext("Matches every character between a and z"),
                "[a-z]",
                "aaa 1 bbb 2 ccc 3"
            ),
            self.new_example_row(
                &gettext("Matches both an a or a b"),
                "a|b",
                "aaa bbb ccc"
            ),
            self.new_example_row(
                &gettext("Matches every word character, equivalent to [a-zA-Z0-9_]"),
                "\\w",
                "aaa bbb1 Ccc2"
            ),
            self.new_example_row(
                &gettext("Matches every digit character, equivalent to [0-9]"),
                "\\d",
                "aaa bbb ccc 123 123"
            ),
        ];

        examples.iter().for_each(|example| {
            self.imp().common_preferences_group
                .add(example)
        });
    }

    pub fn load_anchors_group(&self) {
        let examples = [
            self.new_example_row(
                &gettext("Matches the start of the string"),
                "^",
                "aaa bbb ccc 123 123"
            ),
            self.new_example_row(
                &gettext("Matches the end of the string"),
                "$",
                "aaa bbb ccc 123 123"
            ),
        ];

        examples.iter().for_each(|example| {
            self.imp().anchors_preferences_group
                .add(example)
        });
    }

    pub fn load_quantifiers_group(&self) {
        let examples = [
            self.new_example_row(
                &gettext("Matches zero or more of a"),
                "a*",
                "bbb ccc"
            ),
            self.new_example_row(
                &gettext("Matches on or more of a"),
                "a+",
                "aaa bbb ccc"
            ),
            self.new_example_row(
                &gettext("Matches exactly 2 of consecutive 'a' characters"),
                "a{2}",
                "aaa aaaa bb"
            ),
        ];

        examples.iter().for_each(|example| {
            self.imp().quantifiers_preferences_group
                .add(example)
        });
    }

    fn new_example_row(&self, subtitle: &str, regex: &str, _test_string: &str) -> adw::ActionRow {
        adw::ActionRow::builder()
            .title(regex)
            .subtitle(subtitle)
            .title_selectable(true)
            .build()
    }
}
