/*
 * digger-vala - DNS lookup tool with GTK interface
 * Copyright (C) 2024 tobagin
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 */

namespace Digger {
#if DEVELOPMENT
    [GtkTemplate (ui = "/io/github/tobagin/digger/Devel/enhanced-query-form.ui")]
#else
    [GtkTemplate (ui = "/io/github/tobagin/digger/enhanced-query-form.ui")]
#endif
    public class EnhancedQueryForm : Adw.PreferencesGroup {
        [GtkChild] private unowned Gtk.Entry domain_entry;
        [GtkChild] private unowned Gtk.DropDown record_type_dropdown;
        [GtkChild] private unowned Gtk.DropDown preset_dropdown;
        [GtkChild] private unowned Gtk.Button query_button;
        [GtkChild] private unowned Gtk.Button favorite_button;
        [GtkChild] private unowned Gtk.Button paste_button;
        [GtkChild] private unowned Gtk.DropDown dns_server_dropdown;
        [GtkChild] private unowned Gtk.Box quick_presets_box;
        [GtkChild] private unowned Gtk.Switch reverse_lookup_switch;
        [GtkChild] private unowned Gtk.Switch trace_path_switch;
        [GtkChild] private unowned Gtk.Switch short_output_switch;
        [GtkChild] private unowned Gtk.Switch dnssec_switch;
        [GtkChild] private unowned Gtk.Switch ttl_details_switch;

        private AutocompleteDropdown autocomplete_dropdown;

        private DnsPresets dns_presets;
        private QueryHistory query_history;
        private FavoritesManager favorites_manager;
        private PresetManager preset_manager;
        private string current_dns_server = "";
        private bool signals_connected = false;
        private bool _query_in_progress = false;
        private GLib.Settings settings;
        private QueryPreset? active_preset = null;
        private bool applying_preset = false;
        
        public signal void query_requested (string domain, RecordType record_type, string? dns_server, bool request_dnssec);
        
        public bool query_in_progress { 
            get { return _query_in_progress; }
            set { 
                _query_in_progress = value;
                domain_entry.sensitive = !value;
                record_type_dropdown.sensitive = !value;
                dns_server_dropdown.sensitive = !value;
                
                if (value) {
                    query_button.label = "Querying...";
                    query_button.sensitive = false;
                } else {
                    query_button.label = "Look up DNS records";
                    // Re-validate to set correct button state
                    validate_input ();
                }
            }
        }
        
        public EnhancedQueryForm () {
            // dns_presets will be set via set_dns_presets() after construction
        }
        
        construct {
            settings = new GLib.Settings(Config.APP_ID);
            favorites_manager = FavoritesManager.get_instance ();
            preset_manager = PresetManager.get_instance ();
            query_button.sensitive = false;

            if (dns_presets != null) {
                setup_ui ();
                connect_signals ();
            }

            update_favorite_button_state ();
        }
        
        public void set_dns_presets (DnsPresets presets) {
            dns_presets = presets;
            setup_ui ();
            if (!signals_connected) {
                connect_signals ();
                signals_connected = true;
                // Initial validation after signals are connected
                validate_input ();
            }
        }
        
        public void set_query_history (QueryHistory history) {
            query_history = history;
            
            // Connect autocomplete to query history
            autocomplete_dropdown.set_query_history (history);
            
            setup_domain_suggestions ();
        }
        
        private void setup_ui () {
            if (dns_presets == null) {
                return; // Cannot setup UI without presets
            }
            
            // Initialize autocomplete dropdown with domain entry from template
            if (autocomplete_dropdown == null) {
                autocomplete_dropdown = new AutocompleteDropdown (domain_entry);
            }
            
            setup_record_type_dropdown ();
            setup_dns_server_dropdown ();
            setup_preset_dropdown ();
            setup_quick_presets ();
            load_default_preferences ();
        }
        
        private void setup_record_type_dropdown () {
            var model = new Gtk.StringList (null);
            var record_types = dns_presets.get_all_record_types ();
            
            // Sort by type name for consistent display
            var sorted_types = new Gee.ArrayList<RecordTypeInfo> ();
            sorted_types.add_all (record_types);
            sorted_types.sort ((a, b) => {
                // Put common types first
                string[] common_order = {"A", "AAAA", "CNAME", "MX", "NS", "TXT"};
                int pos_a = -1, pos_b = -1;
                for (int i = 0; i < common_order.length; i++) {
                    if (a.record_type == common_order[i]) pos_a = i;
                    if (b.record_type == common_order[i]) pos_b = i;
                }
                
                if (pos_a >= 0 && pos_b >= 0) return pos_a - pos_b;
                if (pos_a >= 0) return -1;
                if (pos_b >= 0) return 1;
                return strcmp (a.record_type, b.record_type);
            });
            
            foreach (var record_type in sorted_types) {
                model.append (record_type.get_display_name ());
            }
            
            // Set up the dropdown model (template widget is already created)
            record_type_dropdown.model = model;
            
            // Load default record type from settings and find its index
            var default_record_type = settings.get_string ("default-record-type");
            if (default_record_type == "") {
                default_record_type = "A"; // fallback to A if empty
            }
            int selected_index = 0; // fallback to first item
            
            for (uint i = 0; i < model.get_n_items (); i++) {
                var display_name = model.get_string (i);
                var type_code = display_name.split (" - ")[0];
                if (type_code == default_record_type) {
                    selected_index = (int)i;
                    break;
                }
            }
            record_type_dropdown.selected = selected_index;
            
            // Add tooltips based on selection
            record_type_dropdown.notify["selected"].connect (() => {
                var selected_name = model.get_string (record_type_dropdown.selected);
                var type_code = selected_name.split (" - ")[0];
                var info = dns_presets.get_record_type_info (type_code);
                if (info != null) {
                    record_type_dropdown.tooltip_text = info.get_tooltip_text ();
                }
            });
        }
        
        private void load_default_preferences () {
            // Load default switch states from preferences
            reverse_lookup_switch.active = settings.get_boolean ("default-reverse-lookup");
            trace_path_switch.active = settings.get_boolean ("default-trace-path");
            short_output_switch.active = settings.get_boolean ("default-short-output");
        }
        
        private void setup_dns_server_dropdown () {
            var model = new Gtk.StringList (null);
            var dns_servers = new Gee.ArrayList<DnsServer> ();
            
            // Add system default as first option
            model.append ("System Default");
            
            // Add all DNS servers from presets
            var all_servers = dns_presets.get_dns_servers ();
            foreach (var server in all_servers) {
                dns_servers.add (server);
                model.append (server.get_display_name ());
            }
            
            // Add custom option
            model.append ("Custom DNS Server...");
            
            dns_server_dropdown.model = model;
            
            // Load default DNS server from settings and find its index
            var default_dns_server = settings.get_string ("default-dns-server");
            int selected_index = 0; // fallback to System Default
            
            if (default_dns_server != "") {
                // Look for matching DNS server
                for (int i = 0; i < all_servers.size; i++) {
                    var server = all_servers.get (i);
                    if (server.primary == default_dns_server || server.name == default_dns_server) {
                        selected_index = i + 1; // +1 because System Default is at index 0
                        break;
                    }
                }
            }
            
            dns_server_dropdown.selected = selected_index;
            
            // Store the dns_servers list for quick access
            dns_server_dropdown.set_data ("dns_servers", dns_servers);
            
            // Add tooltips and handle selection changes
            dns_server_dropdown.notify["selected"].connect (() => {
                var current_selected_index = dns_server_dropdown.selected;
                var selected_text = model.get_string (current_selected_index);
                
                if (current_selected_index == 0) {
                    // System Default
                    current_dns_server = "";
                    dns_server_dropdown.tooltip_text = "Use system default DNS server";
                } else if (current_selected_index == model.get_n_items () - 1) {
                    // Custom DNS Server option
                    show_custom_dns_dialog ();
                } else {
                    // Preset DNS server
                    var server = dns_servers.get ((int)(current_selected_index - 1));
                    current_dns_server = server.primary;
                    dns_server_dropdown.tooltip_text = server.get_tooltip_text ();
                }
            });
        }
        
        private void setup_preset_dropdown () {
            var model = new Gtk.StringList (null);

            // Add "No preset" option
            model.append ("No preset selected");

            // Add separator marker
            model.append ("─ System Presets ─");

            // Add system presets
            var system_presets = preset_manager.get_system_presets ();
            foreach (var preset in system_presets) {
                model.append (preset.get_display_name ());
            }

            // Add user presets if any exist
            var user_presets = preset_manager.get_user_presets ();
            if (user_presets.size > 0) {
                model.append ("─ Custom Presets ─");
                foreach (var preset in user_presets) {
                    model.append (preset.get_display_name ());
                }
            }

            preset_dropdown.model = model;
            preset_dropdown.selected = 0; // Start with "No preset selected"

            // Handle preset selection
            preset_dropdown.notify["selected"].connect (on_preset_selected);

            // Listen for preset updates
            preset_manager.presets_updated.connect (() => {
                refresh_preset_dropdown ();
            });
        }

        private void refresh_preset_dropdown () {
            var model = new Gtk.StringList (null);

            // Add "No preset" option
            model.append ("No preset selected");

            // Add separator marker
            model.append ("─ System Presets ─");

            // Add system presets
            var system_presets = preset_manager.get_system_presets ();
            foreach (var preset in system_presets) {
                model.append (preset.get_display_name ());
            }

            // Add user presets if any exist
            var user_presets = preset_manager.get_user_presets ();
            if (user_presets.size > 0) {
                model.append ("─ Custom Presets ─");
                foreach (var preset in user_presets) {
                    model.append (preset.get_display_name ());
                }
            }

            preset_dropdown.model = model;
        }

        private void on_preset_selected () {
            if (applying_preset) {
                return; // Avoid recursion when we're programmatically changing settings
            }

            var model = preset_dropdown.model as Gtk.StringList;
            var selected_index = preset_dropdown.selected;
            var selected_text = model.get_string (selected_index);

            // Check if it's the "No preset" or separator option
            if (selected_index == 0 || selected_text.has_prefix ("─")) {
                active_preset = null;
                if (selected_text.has_prefix ("─")) {
                    // User clicked a separator, reset to "No preset"
                    preset_dropdown.selected = 0;
                }
                return;
            }

            // Find the preset by name
            var all_presets = preset_manager.get_all_presets ();
            QueryPreset? found_preset = null;

            foreach (var preset in all_presets) {
                if (preset.get_display_name () == selected_text) {
                    found_preset = preset;
                    break;
                }
            }

            if (found_preset != null) {
                apply_preset (found_preset);
            }
        }

        private void apply_preset (QueryPreset preset) {
            applying_preset = true;
            active_preset = preset;

            // Apply record type
            set_record_type (preset.record_type);

            // Apply DNS server
            if (preset.dns_server != null && preset.dns_server.length > 0) {
                set_dns_server (preset.dns_server);
            } else {
                set_dns_server (""); // System default
            }

            // Apply switches
            reverse_lookup_switch.active = preset.reverse_lookup;
            trace_path_switch.active = preset.trace_path;
            short_output_switch.active = preset.short_output;
            dnssec_switch.active = false; // Presets don't store DNSSEC preference yet

            applying_preset = false;

            // Show a toast notification
            show_preset_applied_toast (preset.name);
        }

        private void show_preset_applied_toast (string preset_name) {
            var parent = get_parent ();
            while (parent != null && !(parent is Adw.ToastOverlay)) {
                parent = parent.get_parent ();
            }

            if (parent is Adw.ToastOverlay) {
                var toast_overlay = (Adw.ToastOverlay) parent;
                var toast = new Adw.Toast (@"Applied preset: $preset_name") {
                    timeout = Constants.TOAST_TIMEOUT_SECONDS
                };
                toast_overlay.add_toast (toast);
            }
        }

        private void setup_quick_presets () {
            // Clear any existing preset buttons first
            var child = quick_presets_box.get_first_child ();
            while (child != null) {
                var next = child.get_next_sibling ();
                quick_presets_box.remove (child);
                child = next;
            }

            // quick_presets_box is from template, just add buttons to it

            // Add Google DNS preset
            add_quick_preset_button ("Google", "8.8.8.8");

            // Add Cloudflare DNS preset
            add_quick_preset_button ("Cloudflare", "1.1.1.1");

            // Add Quad9 DNS preset
            add_quick_preset_button ("Quad9", "9.9.9.9");
        }
        
        private void add_quick_preset_button (string name, string ip) {
            var preset_button = new Gtk.Button.with_label (name) {
                tooltip_text = @"Use $name DNS ($ip)",
                halign = Gtk.Align.CENTER,
                valign = Gtk.Align.CENTER
            };
            // preset_button.add_css_class ("pill");
            preset_button.clicked.connect (() => {
                set_dns_server_by_ip (ip);
            });
            quick_presets_box.append (preset_button);
        }
        
        private void setup_domain_suggestions () {
            if (query_history == null) return;
            
            // Autocomplete system is already set up through the AutocompleteDropdown
            // The dropdown will automatically use the query history for suggestions
        }
        
        private void connect_signals () {
            favorite_button.clicked.connect (on_favorite_clicked);
            paste_button.clicked.connect (paste_from_clipboard);
            domain_entry.activate.connect (on_query_requested);
            query_button.clicked.connect (on_query_requested);

            // Real-time validation
            domain_entry.changed.connect (() => {
                validate_input ();
                update_favorite_button_state ();
            });

            // Connect autocomplete signals if dropdown exists
            if (autocomplete_dropdown != null) {
                autocomplete_dropdown.suggestion_selected.connect (on_autocomplete_selected);
            }
        }
        
        public bool get_reverse_lookup () {
            return reverse_lookup_switch.active;
        }
        
        public bool get_trace_path () {
            return trace_path_switch.active;
        }
        
        public bool get_short_output () {
            return short_output_switch.active;
        }
        
        public void set_reverse_lookup (bool value) {
            reverse_lookup_switch.active = value;
        }
        
        public void set_trace_path (bool value) {
            trace_path_switch.active = value;
        }
        
        public void set_short_output (bool value) {
            short_output_switch.active = value;
        }

        public bool get_request_dnssec () {
            return dnssec_switch.active;
        }

        public void set_request_dnssec (bool value) {
            dnssec_switch.active = value;
        }

        public bool get_show_detailed_ttl () {
            return ttl_details_switch.active;
        }

        public void set_show_detailed_ttl (bool value) {
            ttl_details_switch.active = value;
        }
        
        private void validate_input () {
            string domain = domain_entry.text.strip ();
            bool is_valid = domain.length > 0;
            
            // Basic domain/IP validation
            if (domain.length > 0) {
                is_valid = is_valid_domain_or_ip (domain);
            }
            
            query_button.sensitive = is_valid && !query_in_progress;
            
            if (!is_valid && domain.length > 0) {
                domain_entry.add_css_class ("error");
            } else {
                domain_entry.remove_css_class ("error");
            }
        }
        
        private bool is_valid_domain_or_ip (string input) {
            // Trim whitespace
            string domain_to_check = input.strip ();
            
            // Auto-strip URL components for validation check
            if (domain_to_check.has_prefix ("http://") || domain_to_check.has_prefix ("https://")) {
                try {
                    // Use Uri to parse and extract host
                    var uri = GLib.Uri.parse (domain_to_check, GLib.UriFlags.NONE);
                    if (uri.get_host () != null) {
                        domain_to_check = uri.get_host ();
                    }
                } catch (Error e) {
                    // Fallback to manual stripping if Uri parsing fails
                    int schema_end = domain_to_check.index_of ("://");
                    if (schema_end != -1) {
                        domain_to_check = domain_to_check.substring (schema_end + 3);
                    }
                    int path_start = domain_to_check.index_of ("/");
                    if (path_start != -1) {
                        domain_to_check = domain_to_check.substring (0, path_start);
                    }
                }
            }

            if (domain_to_check.length == 0 || domain_to_check.length > 253) {
                return false;
            }
            
            // Try IDN conversion first
            string? ascii_input = GLib.Hostname.to_ascii (domain_to_check);
            if (ascii_input == null) {
                // FALLBACK: GLib conversion failed. Use permissive check to allow query if safe.
                
                // 1. Check for command injection (leading hyphen)
                if (domain_to_check.has_prefix ("-")) {
                    return false;
                }
                
                // 2. Check for whitespace
                try {
                    if (Regex.match_simple ("\\s", domain_to_check)) {
                        return false;
                    }
                } catch (RegexError e) {
                    return false;
                }
                
                // 3. Check for shell meta-characters [;&|`$]
                try {
                    if (Regex.match_simple ("[;&|`$]", domain_to_check)) {
                         return false;
                    }
                } catch (RegexError e) {
                    return false;
                }
                
                // If it looks safe, allow it. Let 'dig' complain if it's invalid DNS.
                return true;
            }
            
            // Prevent command injection checks
            if (ascii_input.has_prefix ("-")) {
                return false;
            }
            
            // If it converts to ASCII successfully and isn't a flag, we accept it.
            // We trust to_ascii + dig to handle (or fail gracefully on) other chars.
            return true;
        }
        
        private void set_dns_server_by_ip (string ip) {
            var model = dns_server_dropdown.model as Gtk.StringList;
            var dns_servers = dns_server_dropdown.get_data<Gee.ArrayList<DnsServer>> ("dns_servers");
            
            // Look for the server by IP in our list
            for (int i = 0; i < dns_servers.size; i++) {
                var server = dns_servers.get (i);
                if (server.primary == ip) {
                    // Found it, select this item (add 1 for system default offset)
                    dns_server_dropdown.selected = (uint)(i + 1);
                    return;
                }
            }
        }
        
        private void show_custom_dns_dialog () {
            var dialog = new Adw.AlertDialog ("Custom DNS Server", "Enter a custom DNS server address:");

            var entry = new Gtk.Entry () {
                placeholder_text = "e.g., 1.1.1.1 or dns.example.com"
            };

            dialog.set_extra_child (entry);
            dialog.add_response ("cancel", "Cancel");
            dialog.add_response ("ok", "OK");
            dialog.set_response_appearance ("ok", Adw.ResponseAppearance.SUGGESTED);
            dialog.set_default_response ("ok");

            var window = get_root () as Gtk.Window;
            if (window == null) {
                warning ("Cannot show dialog: no parent window found");
                return;
            }

            dialog.response.connect_after ((response) => {
                if (response == "ok") {
                    var custom_server = entry.text.strip ();
                    if (custom_server.length > 0) {
                        // Validate DNS server address (SEC-001)
                        if (ValidationUtils.validate_dns_server (custom_server)) {
                            // Add custom server to the model
                            add_custom_dns_server (custom_server);
                        } else {
                            // Show validation error
                            show_dns_validation_error (custom_server);
                            // Go back to system default
                            dns_server_dropdown.selected = 0;
                        }
                    } else {
                        // Go back to system default if empty
                        dns_server_dropdown.selected = 0;
                    }
                } else {
                    // Cancel - go back to previous selection or system default
                    dns_server_dropdown.selected = 0;
                }
            });

            dialog.present (window);
        }

        private void show_dns_validation_error (string invalid_server) {
            var error_message = ValidationUtils.get_dns_server_error_message (invalid_server);
            var window = get_root () as Gtk.Window;
            if (window == null) {
                warning ("Cannot show error dialog: no parent window found");
                return;
            }

            var error_dialog = new Adw.AlertDialog ("Invalid DNS Server", error_message);
            error_dialog.add_response ("ok", "OK");
            error_dialog.set_response_appearance ("ok", Adw.ResponseAppearance.DESTRUCTIVE);
            error_dialog.set_default_response ("ok");

            error_dialog.present (window);
        }
        
        private void add_custom_dns_server (string server_ip) {
            var model = dns_server_dropdown.model as Gtk.StringList;
            var dns_servers = dns_server_dropdown.get_data<Gee.ArrayList<DnsServer>> ("dns_servers");
            
            // Create a custom DNS server entry
            var custom_server = new DnsServer ();
            custom_server.name = "Custom";
            custom_server.primary = server_ip;
            custom_server.description = @"Custom DNS server ($server_ip)";
            custom_server.category = "custom";
            
            // Check if this custom server already exists
            for (int i = 0; i < dns_servers.size; i++) {
                var existing = dns_servers.get (i);
                if (existing.category == "custom" && existing.primary == server_ip) {
                    // Already exists, just select it
                    dns_server_dropdown.selected = (uint)(i + 1);
                    return;
                }
            }
            
            // Remove old custom servers from the model and list
            for (int i = dns_servers.size - 1; i >= 0; i--) {
                var existing = dns_servers.get (i);
                if (existing.category == "custom") {
                    dns_servers.remove_at (i);
                    model.remove (i + 1); // +1 for system default offset
                }
            }
            
            // Add the new custom server
            var last_index = model.get_n_items () - 1;
            dns_servers.add (custom_server);
            
            // Get the "Custom DNS Server..." option and remove it temporarily
            var custom_option_text = model.get_string (last_index);
            model.remove (last_index);
            
            // Add the new server, then re-add the "Custom DNS Server..." option
            model.append (custom_server.get_display_name ());
            model.append (custom_option_text);
            
            // Select the new custom server
            dns_server_dropdown.selected = (uint)last_index;
            current_dns_server = server_ip;
        }
        
        private void paste_from_clipboard () {
            var clipboard = Gdk.Display.get_default ().get_clipboard ();
            clipboard.read_text_async.begin (null, (obj, result) => {
                try {
                    string? text = clipboard.read_text_async.end (result);
                    if (text != null && text.strip ().length > 0) {
                        domain_entry.text = text.strip ();
                        validate_input ();
                    }
                } catch (Error e) {
                    warning ("Error pasting from clipboard: %s", e.message);
                }
            });
        }
        
        private void on_query_requested () {
            if (query_in_progress) return;
            
            string domain = domain_entry.text.strip ();
            if (domain.length == 0) return;
            
            // Strip URL components if present
            if (domain.has_prefix ("http://") || domain.has_prefix ("https://")) {
                try {
                    var uri = GLib.Uri.parse (domain, GLib.UriFlags.NONE);
                    if (uri.get_host () != null) {
                        domain = uri.get_host ();
                    }
                } catch (Error e) {
                    // Fallback manual strip
                    int schema_end = domain.index_of ("://");
                    if (schema_end != -1) {
                        domain = domain.substring (schema_end + 3);
                    }
                    int path_start = domain.index_of ("/");
                    if (path_start != -1) {
                        domain = domain.substring (0, path_start);
                    }
                }
                
                // Update the entry to show the cleaned domain
                domain_entry.text = domain;
            }
            
            var selected_text = ((Gtk.StringList) record_type_dropdown.model).get_string (record_type_dropdown.selected);
            string record_type_str = selected_text.split (" - ")[0];
            RecordType record_type = RecordType.from_string (record_type_str);
            
            string? dns_server = current_dns_server.length > 0 ? current_dns_server : null;
            
            query_requested (domain, record_type, dns_server, dnssec_switch.active);
        }
        
        public string get_domain () {
            return domain_entry.text.strip ();
        }
        
        public void set_domain (string domain) {
            domain_entry.text = domain;
            validate_input ();
        }
        
        public void set_domain_from_history (string domain) {
            if (autocomplete_dropdown != null) {
                autocomplete_dropdown.set_domain_without_autocomplete (domain);
            } else {
                domain_entry.text = domain;
            }
            validate_input ();
        }
        
        public RecordType get_record_type () {
            var selected_text = ((Gtk.StringList) record_type_dropdown.model).get_string (record_type_dropdown.selected);
            string record_type_str = selected_text.split (" - ")[0];
            return RecordType.from_string (record_type_str);
        }
        
        public void set_record_type (RecordType record_type) {
            var model = (Gtk.StringList) record_type_dropdown.model;
            for (uint i = 0; i < model.get_n_items (); i++) {
                string item_text = model.get_string (i);
                string item_type = item_text.split (" - ")[0];
                if (item_type == record_type.to_string ()) {
                    record_type_dropdown.selected = i;
                    break;
                }
            }
        }
        
        public string? get_dns_server () {
            return current_dns_server.length > 0 ? current_dns_server : null;
        }
        
        public void set_dns_server (string server) {
            if (server.length == 0) {
                dns_server_dropdown.selected = 0; // System default
            } else {
                set_dns_server_by_ip (server);
            }
        }
        
        public void focus_domain_entry () {
            domain_entry.grab_focus ();
        }
        
        public void clear_form () {
            domain_entry.text = "";
            
            // Reset record type to default from settings
            var default_record_type = settings.get_string ("default-record-type");
            if (default_record_type == "") {
                default_record_type = "A"; // fallback
            }
            var model = (Gtk.StringList) record_type_dropdown.model;
            int selected_index = 0; // fallback to first item
            
            for (uint i = 0; i < model.get_n_items (); i++) {
                var display_name = model.get_string (i);
                var type_code = display_name.split (" - ")[0];
                if (type_code == default_record_type) {
                    selected_index = (int)i;
                    break;
                }
            }
            
            record_type_dropdown.selected = selected_index;
            
            // Reset DNS server to default from settings
            var default_dns_server = settings.get_string ("default-dns-server");
            int dns_selected_index = 0; // fallback to System Default
            
            if (default_dns_server != "") {
                var dns_servers = dns_server_dropdown.get_data<Gee.ArrayList<DnsServer>> ("dns_servers");
                if (dns_servers != null) {
                    for (int i = 0; i < dns_servers.size; i++) {
                        var server = dns_servers.get (i);
                        if (server.primary == default_dns_server || server.name == default_dns_server) {
                            dns_selected_index = i + 1; // +1 because System Default is at index 0
                            break;
                        }
                    }
                }
            }
            
            dns_server_dropdown.selected = dns_selected_index;
            
            // Reset switches to default preferences
            reverse_lookup_switch.active = settings.get_boolean ("default-reverse-lookup");
            trace_path_switch.active = settings.get_boolean ("default-trace-path");
            short_output_switch.active = settings.get_boolean ("default-short-output");
            dnssec_switch.active = false;
            ttl_details_switch.active = false;
            
            validate_input ();
        }
        
        public void clear_domain_only () {
            // Clear only the domain field, keep all other settings
            domain_entry.text = "";
            validate_input ();
        }
        
        public void trigger_query () {
            on_query_requested ();
        }
        
        /**
         * Handle autocomplete suggestion selection
         */
        private void on_autocomplete_selected (string domain) {
            // The domain is already set in the entry by the autocomplete dropdown
            // Just validate the input
            validate_input ();
            
            // Optionally trigger query immediately if user preference is set
            // For now, just focus remains on the domain entry for user confirmation
        }
        
        /**
         * Show autocomplete suggestions programmatically
         */
        public void show_suggestions () {
            autocomplete_dropdown.trigger_suggestions ();
        }
        
        /**
         * Hide autocomplete suggestions
         */
        public void hide_suggestions () {
            autocomplete_dropdown.clear_suggestions ();
        }

        private void on_favorite_clicked () {
            var domain = domain_entry.text.strip ();
            if (domain.length == 0) {
                return;
            }

            var record_type = get_record_type ();
            var is_favorite = favorites_manager.is_favorite (domain, record_type);

            if (is_favorite) {
                var entry = favorites_manager.get_favorite (domain, record_type);
                if (entry != null) {
                    favorites_manager.remove_favorite (entry);
                    show_favorite_removed_toast (domain);
                }
            } else {
                var entry = new FavoriteEntry (domain, record_type);
                entry.label = domain;
                entry.dns_server = current_dns_server.length > 0 ? current_dns_server : null;
                favorites_manager.add_favorite (entry);
                show_favorite_added_toast (domain);
            }

            update_favorite_button_state ();
        }

        private void update_favorite_button_state () {
            var domain = domain_entry.text.strip ();
            if (domain.length == 0) {
                favorite_button.icon_name = "starred-symbolic";
                favorite_button.tooltip_text = "Add to favorites";
                return;
            }

            var record_type = get_record_type ();
            var is_favorite = favorites_manager.is_favorite (domain, record_type);
            if (is_favorite) {
                favorite_button.icon_name = "star-filled-symbolic";
                favorite_button.tooltip_text = "Remove from favorites";
            } else {
                favorite_button.icon_name = "starred-symbolic";
                favorite_button.tooltip_text = "Add to favorites";
            }
        }

        private void show_favorite_added_toast (string domain) {
            var parent = get_parent ();
            while (parent != null && !(parent is Adw.ToastOverlay)) {
                parent = parent.get_parent ();
            }

            if (parent is Adw.ToastOverlay) {
                var toast_overlay = (Adw.ToastOverlay) parent;
                var toast = new Adw.Toast (@"Added $domain to favorites") {
                    timeout = Constants.TOAST_TIMEOUT_SECONDS
                };
                toast_overlay.add_toast (toast);
            }
        }

        private void show_favorite_removed_toast (string domain) {
            var parent = get_parent ();
            while (parent != null && !(parent is Adw.ToastOverlay)) {
                parent = parent.get_parent ();
            }

            if (parent is Adw.ToastOverlay) {
                var toast_overlay = (Adw.ToastOverlay) parent;
                var toast = new Adw.Toast (@"Removed $domain from favorites") {
                    timeout = Constants.TOAST_TIMEOUT_SECONDS
                };
                toast_overlay.add_toast (toast);
            }
        }
    }
}
