namespace StillExplore {
    public class Window : Adw.ApplicationWindow {
        private const int ACTION_ICON_SIZE = 40;
        protected Adw.Breakpoint breakpoint;
        protected Adw.BreakpointCondition breakpoint_condition;
        protected Adw.NavigationSplitView navigation_split_view;
        protected Adw.NavigationPage sidebar_page;
        protected Adw.HeaderBar sidebar_header;
        protected Adw.HeaderBar content_header;
        protected Adw.WindowTitle content_title;
        protected Gtk.Stack stack;
        protected Gtk.ListBox sidebar_list;
        protected Gee.ArrayList<string> sidebar_page_ids;
        protected Gee.HashMap<string, string> content_titles;
        protected Config config;

        public Window(Adw.Application app) {
            Object(
                application: app,
                title: _("Explore stillOS")
            );

            set_default_size(760, 540);
            set_resizable(false);

            // Load config first
            config = Config.load_from_file(CONFIG_FILE_PATH);
            if (config == null) {
                warning("Failed to load config, using default title");
                set_title(_("Explore stillOS"));
            } else {
                set_title(config.app.app_title);
            }

            setup_ui();
            load_pages_from_config();
        }

        private void setup_ui() {
            // Navigation Split View
            navigation_split_view = new Adw.NavigationSplitView();
            content_titles = new Gee.HashMap<string, string>();
            sidebar_page_ids = new Gee.ArrayList<string>();

            // Create sidebar toolbar view
            var sidebar_toolbar = new Adw.ToolbarView();
            sidebar_toolbar.set_top_bar_style(Adw.ToolbarStyle.FLAT);

            // Sidebar Header
            sidebar_header = new Adw.HeaderBar();
            var title_widget = new Adw.WindowTitle(config?.app.app_title ?? _("Explore stillOS"), "");
            sidebar_header.set_title_widget(title_widget);
            sidebar_header.set_show_start_title_buttons(true);
            sidebar_header.set_show_end_title_buttons(false);
            sidebar_toolbar.add_top_bar(sidebar_header);
            
            // Stack for main content
            stack = new Gtk.Stack();
            stack.set_vexpand(true);
            stack.set_hexpand(true);

            var content_toolbar = new Adw.ToolbarView();
            content_toolbar.set_top_bar_style(Adw.ToolbarStyle.FLAT);
            content_header = new Adw.HeaderBar();
            content_header.set_show_start_title_buttons(false);
            content_header.set_show_end_title_buttons(true);
            content_title = new Adw.WindowTitle("", "");
            content_header.set_title_widget(content_title);
            content_toolbar.add_top_bar(content_header);
            content_toolbar.set_content(stack);

            stack.notify["visible-child"].connect(() => {
                update_content_title();
                sync_sidebar_selection();
            });

            // Sidebar list for navigation
            sidebar_list = new Gtk.ListBox();
            sidebar_list.add_css_class("navigation-sidebar");
            sidebar_list.set_selection_mode(Gtk.SelectionMode.SINGLE);
            sidebar_list.set_vexpand(true);
            sidebar_list.set_margin_top(6);
            sidebar_list.row_selected.connect((row) => {
                if (row == null) {
                    return;
                }

                var index = row.get_index();
                if (index < 0 || index >= sidebar_page_ids.size) {
                    return;
                }

                var page_id = sidebar_page_ids[index];
                if (stack.get_visible_child_name() != page_id) {
                    stack.set_visible_child_name(page_id);
                }
            });
            sidebar_toolbar.set_content(sidebar_list);

            // Create sidebar navigation page
            sidebar_page = new Adw.NavigationPage(sidebar_toolbar, "sidebar");
            sidebar_page.set_title(_("Navigation"));

            // Set up the navigation split view
            navigation_split_view.set_sidebar(sidebar_page);

            // Wrap the content toolbar in a Navigation Page so split view can
            // manage the headerbar seam between the sidebar and content.
            var stack_page = new Adw.NavigationPage(content_toolbar, "stack");
            navigation_split_view.set_content(stack_page);

            // Set content
            this.set_content(navigation_split_view);
        }

        private void update_content_title() {
            var visible_child = stack.get_visible_child();
            if (visible_child == null) {
                content_title.set_title("");
                return;
            }

            var visible_child_name = stack.get_visible_child_name();
            if (visible_child_name != null && content_titles.has_key(visible_child_name)) {
                content_title.set_title(content_titles[visible_child_name]);
                return;
            }

            var page = stack.get_page(visible_child);
            content_title.set_title(page.get_title() ?? "");
        }

        private void add_sidebar_page(string page_id, string title) {
            var row = new Gtk.ListBoxRow();
            var label = new Gtk.Label(title);
            label.set_xalign(0.0f);
            label.set_margin_top(10);
            label.set_margin_bottom(10);
            label.set_margin_start(12);
            label.set_margin_end(12);
            row.set_child(label);

            sidebar_list.append(row);
            sidebar_page_ids.add(page_id);

            if (sidebar_page_ids.size == 1) {
                sidebar_list.select_row(row);
            }
        }

        private void sync_sidebar_selection() {
            var visible_child_name = stack.get_visible_child_name();
            if (visible_child_name == null) {
                sidebar_list.unselect_all();
                return;
            }

            for (var i = 0; i < sidebar_page_ids.size; i++) {
                if (sidebar_page_ids[i] == visible_child_name) {
                    var row = sidebar_list.get_row_at_index(i);
                    if (row != null && sidebar_list.get_selected_row() != row) {
                        sidebar_list.select_row(row);
                    }
                    return;
                }
            }

            sidebar_list.unselect_all();
        }

        private void load_pages_from_config() {
            if (config == null) {
                create_fallback_page();
                return;
            }

            foreach (var page_config in config.pages) {
                create_page_from_config(page_config);
            }
        }

        private void create_page_from_config(PageConfig page_config) {
            // Create scrolled window for content
            var scrolled_window = new Gtk.ScrolledWindow();
            scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
            scrolled_window.set_vexpand(true);

            // Create main content box
            var content_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 24);
            content_box.set_margin_top(24);
            content_box.set_margin_bottom(24);
            content_box.set_margin_start(24);
            content_box.set_margin_end(24);
            scrolled_window.set_child(content_box);

            // Create groups from config
            foreach (var group_config in page_config.groups) {
                create_group_from_config(content_box, group_config);
            }

            // Add page to stack
            content_titles[page_config.id] = page_config.titlebar ?? page_config.title;
            stack.add_titled(scrolled_window, page_config.id, page_config.title);
            add_sidebar_page(page_config.id, page_config.title);
            update_content_title();
        }

        private void create_group_from_config(Gtk.Box parent_box, GroupConfig group_config) {
            // Create preference group
            var preference_group = new Adw.PreferencesGroup();
            preference_group.set_title(group_config.title);
            
            // Set description if available
            if (group_config.description != null) {
                preference_group.set_description(group_config.description);
            }

            // Create action rows and add them directly to the preference group
            foreach (var action_config in group_config.actions) {
                create_action_row(preference_group, action_config);
            }
            
            parent_box.append(preference_group);
        }

        private void create_action_row(Adw.PreferencesGroup parent, ActionItemConfig action_config) {
            var action_row = new Adw.ActionRow();
            action_row.set_title(action_config.title);
            
            if (action_config.description != null) {
                action_row.set_subtitle(action_config.description);
            }

            // Set icon if available (svg takes priority over icon)
            if (action_config.svg != null) {
                var svg_path = ICONS_DIR_PATH + action_config.svg + ".svg";
                var file = File.new_for_path(svg_path);
                if (file.query_exists()) {
                    try {
                        var pixbuf = new Gdk.Pixbuf.from_file_at_scale(
                            svg_path,
                            ACTION_ICON_SIZE,
                            ACTION_ICON_SIZE,
                            true
                        );
                        var texture = Gdk.Texture.for_pixbuf(pixbuf);
                        var icon = new Gtk.Image.from_paintable(texture);
                        icon.set_pixel_size(ACTION_ICON_SIZE);
                        action_row.add_prefix(icon);
                    } catch (Error e) {
                        warning("Failed to load SVG %s: %s", svg_path, e.message);
                        var icon = new Gtk.Image.from_icon_name("image-missing");
                        icon.set_icon_size(Gtk.IconSize.LARGE);
                        action_row.add_prefix(icon);
                    }
                } else {
                    warning("SVG file not found: %s", svg_path);
                    var icon = new Gtk.Image.from_icon_name("image-missing");
                    icon.set_icon_size(Gtk.IconSize.LARGE);
                    action_row.add_prefix(icon);
                }
            } else if (action_config.icon != null) {
                var icon = new Gtk.Image.from_icon_name(action_config.icon);
                icon.set_pixel_size(ACTION_ICON_SIZE);
                action_row.add_prefix(icon);
            }

            // Create button for the action
            var button = new Gtk.Button();
            button.set_valign(Gtk.Align.CENTER);
            button.add_css_class("flat");
            
            // Set button text and style from config
            if (action_config.action.button_name != null) {
                button.set_label(action_config.action.button_name);
            } else {
                button.set_label(_("Open"));
            }
            
            if (action_config.action.button_style_class != null) {
                button.add_css_class(action_config.action.button_style_class);
            }

            // Connect button action
            button.clicked.connect(() => {
                handle_action(action_config.action);
            });

            action_row.add_suffix(button);
            action_row.set_activatable_widget(button);
            parent.add(action_row);
        }

        private void handle_action(ActionConfig action) {
            switch (action.action_type) {
                case "application":
                    launch_application(action.target);
                    break;
                case "url":
                    open_url(action.target);
                    break;
                case "command":
                    run_command(action.target);
                    break;
                default:
                    warning("Unknown action type: %s", action.action_type);
                    break;
            }
        }

        private void launch_application(string app_id) {
            try {
                var app_info = AppInfo.create_from_commandline(app_id, null, AppInfoCreateFlags.NONE);
                app_info.launch(null, null);
            } catch (Error e) {
                warning("Failed to launch application %s: %s", app_id, e.message);
                show_error_dialog(_("Failed to launch application"), e.message);
            }
        }

        private void open_url(string url) {
            try {
                AppInfo.launch_default_for_uri(url, null);
            } catch (Error e) {
                warning("Failed to open URL %s: %s", url, e.message);
                show_error_dialog(_("Failed to open URL"), e.message);
            }
        }

        private void run_command(string command) {
            try {
                Process.spawn_command_line_async(command);
            } catch (SpawnError e) {
                warning("Failed to run command %s: %s", command, e.message);
                show_error_dialog(_("Failed to run command"), e.message);
            }
        }

        private void show_error_dialog(string title, string message) {
            var dialog = new Adw.AlertDialog(title, message);
            dialog.add_response("ok", _("OK"));
            dialog.set_response_appearance("ok", Adw.ResponseAppearance.SUGGESTED);
            dialog.present(this);
        }

        private void create_fallback_page() {
            var status_page = new Adw.StatusPage();
            status_page.set_icon_name("dialog-error");
            status_page.set_title(_("Configuration Error"));
            status_page.set_description(_("Failed to load configuration file. Please check that the config file exists and is valid."));

            content_titles["error"] = _("Configuration Error");
            stack.add_titled(status_page, "error", _("Error"));
            add_sidebar_page("error", _("Error"));
            update_content_title();
        }
    }
}
