pragma ComponentBehavior: Bound

import QtQuick
import Quickshell
import qs.Common
import qs.Modals.Settings
import qs.Services
import qs.Widgets

Rectangle {
    id: root

    LayoutMirroring.enabled: I18n.isRtl
    LayoutMirroring.childrenInherit: true

    property int currentIndex: 0
    property var parentModal: null

    signal tabChangeRequested(int tabIndex)
    property string _expandedIds: ","
    property string _collapsedIds: ","
    property string _autoExpandedIds: ","
    property bool searchActive: searchField.text.length > 0
    property int searchSelectedIndex: 0
    property int keyboardHighlightIndex: -1
    readonly property int navigationStateDuration: Theme.currentAnimationSpeed === SettingsData.AnimationSpeed.None ? 0 : Anims.settingsNavigationStateDuration

    function focusSearch() {
        searchField.forceActiveFocus();
    }

    function highlightNext() {
        var flatItems = getFlatNavigableItems();
        if (flatItems.length === 0)
            return;
        var currentPos = flatItems.findIndex(item => item.tabIndex === keyboardHighlightIndex);
        if (currentPos === -1) {
            currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
        }
        var nextPos = (currentPos + 1) % flatItems.length;
        keyboardHighlightIndex = flatItems[nextPos].tabIndex;
        autoExpandForTab(keyboardHighlightIndex);
    }

    function highlightPrevious() {
        var flatItems = getFlatNavigableItems();
        if (flatItems.length === 0)
            return;
        var currentPos = flatItems.findIndex(item => item.tabIndex === keyboardHighlightIndex);
        if (currentPos === -1) {
            currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
        }
        var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length;
        keyboardHighlightIndex = flatItems[prevPos].tabIndex;
        autoExpandForTab(keyboardHighlightIndex);
    }

    function selectHighlighted() {
        if (keyboardHighlightIndex < 0)
            return;
        var oldIndex = currentIndex;
        var newIndex = keyboardHighlightIndex;
        tabChangeRequested(newIndex);
        autoCollapseIfNeeded(oldIndex, newIndex);
        keyboardHighlightIndex = -1;
        Qt.callLater(searchField.forceActiveFocus);
    }

    readonly property var categoryStructure: [
        {
            "id": "personalization",
            "text": I18n.tr("Personalization"),
            "icon": "palette",
            "children": [
                {
                    "id": "wallpaper",
                    "text": I18n.tr("Wallpaper"),
                    "icon": "wallpaper",
                    "tabIndex": 0
                },
                {
                    "id": "theme",
                    "text": I18n.tr("Theme & Colors"),
                    "icon": "format_paint",
                    "tabIndex": 10
                },
                {
                    "id": "typography",
                    "text": I18n.tr("Typography & Motion"),
                    "icon": "text_fields",
                    "tabIndex": 14
                },
                {
                    "id": "time_weather",
                    "text": I18n.tr("Time & Weather"),
                    "icon": "schedule",
                    "tabIndex": 1
                },
                {
                    "id": "sounds",
                    "text": I18n.tr("Sounds"),
                    "icon": "volume_up",
                    "tabIndex": 15,
                    "soundsOnly": true
                },
                {
                    "id": "compositor_layout",
                    "text": CompositorService.isNiri ? "Niri" : (CompositorService.isHyprland ? "Hyprland" : "MangoWC"),
                    "icon": "layers",
                    "tabIndex": 37,
                    "layoutCapable": true
                }
            ]
        },
        {
            "id": "dankbar",
            "text": I18n.tr("Dank Bar"),
            "icon": "toolbar",
            "children": [
                {
                    "id": "dankbar_appearance",
                    "text": I18n.tr("Appearance"),
                    "icon": "palette",
                    "tabIndex": 6
                },
                {
                    "id": "dankbar_settings",
                    "text": I18n.tr("Settings"),
                    "icon": "tune",
                    "tabIndex": 3
                },
                {
                    "id": "dankbar_widgets",
                    "text": I18n.tr("Widgets"),
                    "icon": "widgets",
                    "tabIndex": 22
                },
                {
                    "id": "workspaces",
                    "text": I18n.tr("Workspaces"),
                    "icon": "view_module",
                    "tabIndex": 4
                },
                {
                    "id": "frame",
                    "text": I18n.tr("Frame"),
                    "icon": "frame_source",
                    "tabIndex": 33
                }
            ]
        },
        {
            "id": "workspaces_widgets",
            "text": I18n.tr("Widgets & Notifications"),
            "icon": "dashboard",
            "collapsedByDefault": true,
            "children": [
                {
                    "id": "dank_dash",
                    "text": I18n.tr("Dank Dash"),
                    "icon": "space_dashboard",
                    "tabIndex": 43
                },
                {
                    "id": "media_player",
                    "text": I18n.tr("Media Player"),
                    "icon": "music_note",
                    "tabIndex": 16
                },
                {
                    "id": "notifications",
                    "text": I18n.tr("Notifications"),
                    "icon": "notifications",
                    "tabIndex": 17
                },
                {
                    "id": "osd",
                    "text": I18n.tr("On-screen Displays"),
                    "icon": "tune",
                    "tabIndex": 18
                },
                {
                    "id": "desktop_widgets",
                    "text": I18n.tr("Desktop Widgets"),
                    "icon": "widgets",
                    "tabIndex": 27
                }
            ]
        },
        {
            "id": "dock_launcher",
            "text": I18n.tr("Dock & Launcher"),
            "icon": "shelf_auto_hide",
            "collapsedByDefault": true,
            "children": [
                {
                    "id": "dock",
                    "text": I18n.tr("Dock"),
                    "icon": "dock_to_bottom",
                    "tabIndex": 5
                },
                {
                    "id": "launcher",
                    "text": I18n.tr("Launcher"),
                    "icon": "grid_view",
                    "tabIndex": 9
                }
            ]
        },
        {
            "id": "keybinds",
            "text": I18n.tr("Keyboard Shortcuts"),
            "icon": "keyboard",
            "tabIndex": 2,
            "shortcutsOnly": true
        },
        {
            "id": "displays",
            "text": I18n.tr("Displays"),
            "icon": "monitor",
            "collapsedByDefault": true,
            "children": [
                {
                    "id": "display_config",
                    "text": I18n.tr("Configuration"),
                    "icon": "display_settings",
                    "tabIndex": 24
                },
                {
                    "id": "display_gamma",
                    "text": I18n.tr("Gamma Control"),
                    "icon": "brightness_6",
                    "tabIndex": 25
                },
                {
                    "id": "display_widgets",
                    "text": I18n.tr("Widgets", "settings_displays"),
                    "icon": "widgets",
                    "tabIndex": 26
                }
            ]
        },
        {
            "id": "network",
            "text": I18n.tr("Network"),
            "icon": "wifi",
            "dmsOnly": true,
            "children": [
                {
                    "id": "network_status",
                    "text": I18n.tr("Status"),
                    "icon": "lan",
                    "tabIndex": 7
                },
                {
                    "id": "network_ethernet",
                    "text": I18n.tr("Ethernet"),
                    "icon": "settings_ethernet",
                    "tabIndex": 39
                },
                {
                    "id": "network_wifi",
                    "text": I18n.tr("WiFi"),
                    "icon": "wifi",
                    "tabIndex": 40
                },
                {
                    "id": "network_vpn",
                    "text": I18n.tr("VPN"),
                    "icon": "vpn_key",
                    "tabIndex": 41
                }
            ]
        },
        {
            "id": "applications",
            "text": I18n.tr("Applications"),
            "icon": "apps",
            "collapsedByDefault": true,
            "children": [
                {
                    "id": "default_apps",
                    "text": I18n.tr("Default Apps"),
                    "icon": "star",
                    "tabIndex": 34
                },
                {
                    "id": "running_apps",
                    "text": I18n.tr("Running Apps"),
                    "icon": "app_registration",
                    "tabIndex": 19,
                    "hyprlandNiriOnly": true
                },
                {
                    "id": "autostart",
                    "text": I18n.tr("Autostart Apps"),
                    "icon": "line_start",
                    "tabIndex": 36,
                    "autostartOnly": true
                },
                {
                    "id": "window_rules",
                    "text": I18n.tr("Window Rules"),
                    "icon": "select_window",
                    "tabIndex": 38,
                    "windowRulesCapable": true
                }
            ]
        },
        {
            "id": "system",
            "text": I18n.tr("System"),
            "icon": "memory",
            "collapsedByDefault": true,
            "children": [
                {
                    "id": "audio",
                    "text": I18n.tr("Audio"),
                    "icon": "headphones",
                    "tabIndex": 29
                },
                {
                    "id": "mouse_touchpad",
                    "text": I18n.tr("Mouse & Touchpad"),
                    "icon": "mouse",
                    "tabIndex": 44,
                    "niriOnly": true
                },
                {
                    "id": "locale",
                    "text": I18n.tr("Locale"),
                    "icon": "language",
                    "tabIndex": 30
                },
                {
                    "id": "clipboard",
                    "text": I18n.tr("Clipboard"),
                    "icon": "content_paste",
                    "tabIndex": 23,
                    "clipboardOnly": true
                },
                {
                    "id": "printers",
                    "text": I18n.tr("Printers"),
                    "icon": "print",
                    "tabIndex": 8,
                    "cupsOnly": true
                },
                {
                    "id": "multiplexers",
                    "text": I18n.tr("Multiplexers"),
                    "icon": "terminal",
                    "tabIndex": 32
                },
                {
                    "id": "updater",
                    "text": I18n.tr("System Updater"),
                    "icon": "refresh",
                    "tabIndex": 20,
                    "updaterOnly": true
                },
                {
                    "id": "users",
                    "text": I18n.tr("Users"),
                    "icon": "manage_accounts",
                    "tabIndex": 35
                }
            ]
        },
        {
            "id": "power_security",
            "text": I18n.tr("Power & Security"),
            "icon": "security",
            "collapsedByDefault": true,
            "children": [
                {
                    "id": "battery",
                    "text": I18n.tr("Battery"),
                    "icon": "battery_charging_full",
                    "tabIndex": 42
                },
                {
                    "id": "lock_screen",
                    "text": I18n.tr("Lock Screen"),
                    "icon": "lock",
                    "tabIndex": 11
                },
                {
                    "id": "greeter",
                    "text": I18n.tr("Greeter"),
                    "icon": "login",
                    "tabIndex": 31,
                    "greeterOnly": true
                },
                {
                    "id": "power_sleep",
                    "text": I18n.tr("Power & Sleep"),
                    "icon": "power_settings_new",
                    "tabIndex": 21
                }
            ]
        },
        {
            "id": "plugins",
            "text": I18n.tr("Plugins"),
            "icon": "extension",
            "tabIndex": 12
        },
        {
            "id": "separator",
            "separator": true
        },
        {
            "id": "about",
            "text": I18n.tr("About"),
            "icon": "info",
            "tabIndex": 13
        }
    ]

    function isItemVisible(item) {
        if (item.dmsOnly && !NetworkService.networkAvailable)
            return false;
        if (item.cupsOnly && !CupsService.cupsAvailable)
            return false;
        if (item.shortcutsOnly && !KeybindsService.available)
            return false;
        if (item.soundsOnly && !AudioService.soundsAvailable)
            return false;
        if (item.hyprlandNiriOnly && !CompositorService.isNiri && !CompositorService.isHyprland)
            return false;
        if (item.windowRulesCapable && !CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isMango)
            return false;
        if (item.layoutCapable && !CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isMango)
            return false;
        if (item.niriOnly && !CompositorService.isNiri)
            return false;
        if (item.clipboardOnly && (!DMSService.isConnected || DMSService.apiVersion < 23))
            return false;
        if (item.updaterOnly && !SystemUpdateService.sysupdateAvailable)
            return false;
        if (item.greeterOnly && !GreeterService.available)
            return false;
        if (item.autostartOnly && !DesktopService.autostartAvailable)
            return false;
        return true;
    }

    function hasVisibleChildren(category) {
        if (!category.children)
            return false;
        return category.children.some(child => isItemVisible(child));
    }

    function isCategoryVisible(category) {
        if (category.separator)
            return true;
        if (!isItemVisible(category))
            return false;
        if (category.children && !hasVisibleChildren(category))
            return false;
        return true;
    }

    function _setExpanded(id, expanded) {
        var marker = "," + id + ",";
        if (expanded) {
            if (_expandedIds.indexOf(marker) < 0)
                _expandedIds = _expandedIds + id + ",";
            _collapsedIds = _collapsedIds.replace(marker, ",");
        } else {
            _expandedIds = _expandedIds.replace(marker, ",");
            if (_collapsedIds.indexOf(marker) < 0)
                _collapsedIds = _collapsedIds + id + ",";
        }
        SessionData.setSettingsSidebarState(_expandedIds, _collapsedIds);
    }

    function _setAutoExpanded(id, value) {
        var marker = "," + id + ",";
        if (value) {
            if (_autoExpandedIds.indexOf(marker) < 0)
                _autoExpandedIds = _autoExpandedIds + id + ",";
        } else {
            _autoExpandedIds = _autoExpandedIds.replace(marker, ",");
        }
    }

    function _isAutoExpanded(id) {
        return _autoExpandedIds.indexOf("," + id + ",") >= 0;
    }

    function toggleCategory(categoryId) {
        _setExpanded(categoryId, !isCategoryExpanded(categoryId));
        _setAutoExpanded(categoryId, false);
    }

    function isCategoryExpanded(categoryId) {
        if (_collapsedIds.indexOf("," + categoryId + ",") >= 0)
            return false;
        if (_expandedIds.indexOf("," + categoryId + ",") >= 0)
            return true;
        var category = categoryStructure.find(cat => cat.id === categoryId);
        if (category && category.collapsedByDefault)
            return false;
        return true;
    }

    function isChildActive(category) {
        if (!category.children)
            return false;
        return category.children.some(child => child.tabIndex === currentIndex);
    }

    function findParentCategory(tabIndex) {
        for (var i = 0; i < categoryStructure.length; i++) {
            var cat = categoryStructure[i];
            if (cat.children) {
                for (var j = 0; j < cat.children.length; j++) {
                    if (cat.children[j].tabIndex === tabIndex) {
                        return cat;
                    }
                }
            }
        }
        return null;
    }

    function autoExpandForTab(tabIndex) {
        var parent = findParentCategory(tabIndex);
        if (!parent)
            return;

        if (!isCategoryExpanded(parent.id)) {
            _setExpanded(parent.id, true);
            _setAutoExpanded(parent.id, true);
        }
    }

    function autoCollapseIfNeeded(oldTabIndex, newTabIndex) {
        var oldParent = findParentCategory(oldTabIndex);
        var newParent = findParentCategory(newTabIndex);

        if (oldParent && oldParent !== newParent && _isAutoExpanded(oldParent.id)) {
            _setExpanded(oldParent.id, false);
            _setAutoExpanded(oldParent.id, false);
        }
    }

    function navigateNext() {
        var flatItems = getFlatNavigableItems();
        var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
        var oldIndex = currentIndex;
        var newIndex;
        if (currentPos === -1) {
            newIndex = flatItems[0]?.tabIndex ?? 0;
        } else {
            var nextPos = (currentPos + 1) % flatItems.length;
            newIndex = flatItems[nextPos].tabIndex;
        }
        tabChangeRequested(newIndex);
        autoCollapseIfNeeded(oldIndex, newIndex);
        autoExpandForTab(newIndex);
    }

    function navigatePrevious() {
        var flatItems = getFlatNavigableItems();
        var currentPos = flatItems.findIndex(item => item.tabIndex === currentIndex);
        var oldIndex = currentIndex;
        var newIndex;
        if (currentPos === -1) {
            newIndex = flatItems[0]?.tabIndex ?? 0;
        } else {
            var prevPos = (currentPos - 1 + flatItems.length) % flatItems.length;
            newIndex = flatItems[prevPos].tabIndex;
        }
        tabChangeRequested(newIndex);
        autoCollapseIfNeeded(oldIndex, newIndex);
        autoExpandForTab(newIndex);
    }

    function getFlatNavigableItems() {
        var items = [];
        for (var i = 0; i < categoryStructure.length; i++) {
            var cat = categoryStructure[i];
            if (cat.separator || !isCategoryVisible(cat))
                continue;

            if (cat.tabIndex !== undefined && !cat.children) {
                items.push(cat);
            }

            if (cat.children) {
                for (var j = 0; j < cat.children.length; j++) {
                    var child = cat.children[j];
                    if (isItemVisible(child)) {
                        items.push(child);
                    }
                }
            }
        }
        return items;
    }

    function resolveTabIndex(name: string): int {
        if (!name)
            return -1;

        var normalized = name.toLowerCase().replace(/[_\-\s]/g, "");
        if (normalized === "compositor")
            normalized = "workspaces";

        for (var i = 0; i < categoryStructure.length; i++) {
            var cat = categoryStructure[i];
            if (cat.separator)
                continue;

            var catId = (cat.id || "").toLowerCase().replace(/[_\-\s]/g, "");
            if (catId === normalized) {
                if (cat.tabIndex !== undefined)
                    return cat.tabIndex;
                if (cat.children && cat.children.length > 0)
                    return cat.children[0].tabIndex;
            }

            if (cat.children) {
                for (var j = 0; j < cat.children.length; j++) {
                    var child = cat.children[j];
                    var childId = (child.id || "").toLowerCase().replace(/[_\-\s]/g, "");
                    if (childId === normalized)
                        return child.tabIndex;
                }
            }
        }
        return -1;
    }

    property real __maxTextWidth: Math.max(__m1.advanceWidth, __m2.advanceWidth, __m3.advanceWidth, __m4.advanceWidth, __m5.advanceWidth, __m6.advanceWidth)
    property real __calculatedWidth: Math.max(270, __maxTextWidth + Theme.iconSize * 2 + Theme.spacingM * 4 + Theme.spacingS * 2)

    implicitWidth: __calculatedWidth
    width: __calculatedWidth
    height: parent.height
    color: Theme.surfaceContainer
    radius: Theme.cornerRadius

    Component.onCompleted: {
        root._expandedIds = SessionData.settingsSidebarExpandedIds;
        root._collapsedIds = SessionData.settingsSidebarCollapsedIds;
        GreeterService.refresh();
    }

    StyledTextMetrics {
        id: __m1
        font.pixelSize: Theme.fontSizeMedium
        font.weight: Font.Medium
        text: I18n.tr("Widgets & Notifications")
    }
    StyledTextMetrics {
        id: __m2
        font.pixelSize: Theme.fontSizeMedium
        font.weight: Font.Medium
        text: I18n.tr("Typography & Motion")
    }
    StyledTextMetrics {
        id: __m3
        font.pixelSize: Theme.fontSizeMedium
        font.weight: Font.Medium
        text: I18n.tr("Keyboard Shortcuts")
    }
    StyledTextMetrics {
        id: __m4
        font.pixelSize: Theme.fontSizeMedium
        font.weight: Font.Medium
        text: I18n.tr("Power & Security")
    }
    StyledTextMetrics {
        id: __m5
        font.pixelSize: Theme.fontSizeMedium
        font.weight: Font.Medium
        text: I18n.tr("Dock & Launcher")
    }
    StyledTextMetrics {
        id: __m6
        font.pixelSize: Theme.fontSizeMedium
        font.weight: Font.Medium
        text: I18n.tr("Personalization")
    }

    function selectSearchResult(result) {
        if (!result)
            return;
        if (result.section) {
            SettingsSearchService.navigateToSection(result.section);
        }
        var oldIndex = root.currentIndex;
        tabChangeRequested(result.tabIndex);
        autoCollapseIfNeeded(oldIndex, result.tabIndex);
        autoExpandForTab(result.tabIndex);
        keyboardHighlightIndex = -1;
        Qt.callLater(searchField.forceActiveFocus);
    }

    function navigateSearchResults(delta) {
        if (SettingsSearchService.results.length === 0)
            return;
        searchSelectedIndex = Math.max(0, Math.min(searchSelectedIndex + delta, SettingsSearchService.results.length - 1));
    }

    DankFlickable {
        anchors.fill: parent
        clip: true
        contentHeight: sidebarColumn.height

        Column {
            id: sidebarColumn
            width: parent.width
            leftPadding: Theme.spacingS
            rightPadding: Theme.spacingS
            bottomPadding: Theme.spacingL
            topPadding: Theme.spacingM + 2
            spacing: Theme.spacingXXS

            ProfileSection {
                width: parent.width - parent.leftPadding - parent.rightPadding
                parentModal: root.parentModal
            }

            Rectangle {
                width: parent.width - parent.leftPadding - parent.rightPadding
                height: 1
                color: Theme.outline
                opacity: 0.2
            }

            Item {
                width: parent.width - parent.leftPadding - parent.rightPadding
                height: Theme.spacingXS
            }

            DankTextField {
                id: searchField
                width: parent.width - parent.leftPadding - parent.rightPadding
                placeholderText: I18n.tr("Search...")
                normalBorderColor: Theme.outlineMedium
                focusedBorderColor: Theme.primary
                leftIconName: "search"
                leftIconSize: Theme.iconSize - 4
                showClearButton: text.length > 0
                usePopupTransparency: false
                onTextChanged: {
                    SettingsSearchService.search(text);
                    root.searchSelectedIndex = 0;
                }
                keyForwardTargets: [keyHandler]

                Item {
                    id: keyHandler
                    function navNext() {
                        if (root.searchActive) {
                            root.navigateSearchResults(1);
                        } else {
                            root.highlightNext();
                        }
                    }
                    function navPrev() {
                        if (root.searchActive) {
                            root.navigateSearchResults(-1);
                        } else {
                            root.highlightPrevious();
                        }
                    }
                    function navSelect() {
                        if (root.searchActive && SettingsSearchService.results.length > 0) {
                            root.selectSearchResult(SettingsSearchService.results[root.searchSelectedIndex]);
                        } else if (root.keyboardHighlightIndex >= 0) {
                            root.selectHighlighted();
                        }
                    }
                    Keys.onDownPressed: event => {
                        navNext();
                        event.accepted = true;
                    }
                    Keys.onUpPressed: event => {
                        navPrev();
                        event.accepted = true;
                    }
                    Keys.onTabPressed: event => {
                        navNext();
                        event.accepted = true;
                    }
                    Keys.onBacktabPressed: event => {
                        navPrev();
                        event.accepted = true;
                    }
                    Keys.onReturnPressed: event => {
                        navSelect();
                        event.accepted = true;
                    }
                    Keys.onEscapePressed: event => {
                        if (root.searchActive) {
                            searchField.text = "";
                            SettingsSearchService.clear();
                        } else {
                            root.keyboardHighlightIndex = -1;
                        }
                        event.accepted = true;
                    }
                }
            }

            Column {
                id: searchResultsColumn
                width: parent.width - parent.leftPadding - parent.rightPadding
                spacing: Theme.spacingXXS
                visible: root.searchActive

                Item {
                    width: parent.width
                    height: Theme.spacingS
                }

                Repeater {
                    model: ScriptModel {
                        values: SettingsSearchService.results
                    }

                    Rectangle {
                        id: resultDelegate
                        required property int index
                        required property var modelData

                        width: searchResultsColumn.width
                        height: resultContent.height + Theme.spacingM * 2
                        radius: Theme.cornerRadius
                        color: {
                            if (root.searchSelectedIndex === index)
                                return Theme.buttonBg;
                            if (resultMouseArea.containsMouse)
                                return Theme.surfaceHover;
                            return "transparent";
                        }

                        DankRipple {
                            id: resultRipple
                            rippleColor: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText
                            cornerRadius: resultDelegate.radius
                            animationDuration: Anims.settingsNavigationRippleDuration
                        }

                        Row {
                            id: resultContent
                            anchors.left: parent.left
                            anchors.leftMargin: Theme.spacingM
                            anchors.right: parent.right
                            anchors.rightMargin: Theme.spacingM
                            anchors.verticalCenter: parent.verticalCenter
                            spacing: Theme.spacingM

                            DankIcon {
                                name: resultDelegate.modelData.icon || "settings"
                                size: Theme.iconSize - 2
                                color: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText
                                anchors.verticalCenter: parent.verticalCenter
                            }

                            Column {
                                width: parent.width - Theme.iconSize - Theme.spacingM
                                anchors.verticalCenter: parent.verticalCenter
                                spacing: Theme.spacingXXS

                                StyledText {
                                    text: resultDelegate.modelData.label
                                    font.pixelSize: Theme.fontSizeMedium
                                    font.weight: Font.Medium
                                    color: root.searchSelectedIndex === resultDelegate.index ? Theme.buttonText : Theme.surfaceText
                                    width: parent.width
                                    wrapMode: Text.Wrap
                                    horizontalAlignment: Text.AlignLeft
                                }

                                StyledText {
                                    text: resultDelegate.modelData.category
                                    font.pixelSize: Theme.fontSizeSmall - 1
                                    color: root.searchSelectedIndex === resultDelegate.index ? Theme.withAlpha(Theme.buttonText, 0.7) : Theme.surfaceVariantText
                                    width: parent.width
                                    wrapMode: Text.Wrap
                                    horizontalAlignment: Text.AlignLeft
                                }
                            }
                        }

                        MouseArea {
                            id: resultMouseArea
                            anchors.fill: parent
                            hoverEnabled: true
                            cursorShape: Qt.PointingHandCursor
                            onPressed: mouse => resultRipple.trigger(mouse.x, mouse.y)
                            onClicked: root.selectSearchResult(resultDelegate.modelData)
                        }

                        Behavior on color {
                            ColorAnimation {
                                duration: root.navigationStateDuration
                                easing.type: Easing.BezierSpline
                                easing.bezierCurve: Anims.expressiveEffects
                            }
                        }
                    }
                }

                StyledText {
                    width: parent.width
                    text: I18n.tr("No matches")
                    font.pixelSize: Theme.fontSizeSmall
                    color: Theme.surfaceVariantText
                    horizontalAlignment: Text.AlignHCenter
                    visible: searchField.text.length > 0 && SettingsSearchService.results.length === 0
                    topPadding: Theme.spacingM
                }
            }

            Item {
                width: parent.width - parent.leftPadding - parent.rightPadding
                height: Theme.spacingXS
                visible: !root.searchActive
            }

            Repeater {
                model: root.categoryStructure

                delegate: Column {
                    id: categoryDelegate
                    required property int index
                    required property var modelData

                    width: parent.width - parent.leftPadding - parent.rightPadding
                    visible: !root.searchActive && root.isCategoryVisible(modelData)
                    spacing: Theme.spacingXXS

                    Rectangle {
                        width: parent.width
                        height: 1
                        color: Theme.outline
                        opacity: 0.15
                        visible: categoryDelegate.modelData.separator === true
                    }

                    Item {
                        width: parent.width
                        height: Theme.spacingS
                        visible: categoryDelegate.modelData.separator === true
                    }

                    Rectangle {
                        id: categoryRow
                        width: parent.width
                        height: Math.max(Theme.iconSize, Theme.fontSizeMedium) + Theme.spacingS * 2
                        radius: Theme.cornerRadius
                        visible: categoryDelegate.modelData.separator !== true

                        readonly property bool hasTab: categoryDelegate.modelData.tabIndex !== undefined && !categoryDelegate.modelData.children
                        readonly property bool isActive: hasTab && root.currentIndex === categoryDelegate.modelData.tabIndex
                        readonly property bool isHighlighted: hasTab && root.keyboardHighlightIndex === categoryDelegate.modelData.tabIndex

                        color: {
                            if (isActive)
                                return Theme.buttonBg;
                            if (isHighlighted)
                                return Theme.buttonHover;
                            if (categoryMouseArea.containsMouse)
                                return Theme.surfaceHover;
                            return "transparent";
                        }

                        DankRipple {
                            id: categoryRipple
                            rippleColor: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText
                            cornerRadius: categoryRow.radius
                            animationDuration: Anims.settingsNavigationRippleDuration
                        }

                        Row {
                            id: categoryRowContent
                            anchors.left: parent.left
                            anchors.leftMargin: Theme.spacingM
                            anchors.verticalCenter: parent.verticalCenter
                            spacing: Theme.spacingM

                            DankIcon {
                                name: categoryDelegate.modelData.icon || ""
                                size: Theme.iconSize - 2
                                color: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText
                                anchors.verticalCenter: parent.verticalCenter
                            }

                            StyledText {
                                text: categoryDelegate.modelData.text || ""
                                font.pixelSize: Theme.fontSizeMedium
                                font.weight: (categoryRow.isActive || root.isChildActive(categoryDelegate.modelData)) ? Font.Medium : Font.Normal
                                color: categoryRow.isActive ? Theme.buttonText : Theme.surfaceText
                                anchors.verticalCenter: parent.verticalCenter
                            }
                        }

                        DankIcon {
                            id: expandIcon
                            name: root.isCategoryExpanded(categoryDelegate.modelData.id) ? "expand_less" : "expand_more"
                            size: Theme.iconSize - 4
                            color: Theme.surfaceVariantText
                            anchors.right: parent.right
                            anchors.rightMargin: Theme.spacingM
                            anchors.verticalCenter: parent.verticalCenter
                            visible: categoryDelegate.modelData.children !== undefined && categoryDelegate.modelData.children.length > 0
                        }

                        MouseArea {
                            id: categoryMouseArea
                            anchors.fill: parent
                            hoverEnabled: true
                            cursorShape: Qt.PointingHandCursor
                            onPressed: mouse => categoryRipple.trigger(mouse.x, mouse.y)
                            onClicked: {
                                root.keyboardHighlightIndex = -1;
                                if (categoryDelegate.modelData.children) {
                                    root.toggleCategory(categoryDelegate.modelData.id);
                                } else if (categoryDelegate.modelData.tabIndex !== undefined) {
                                    root.tabChangeRequested(categoryDelegate.modelData.tabIndex);
                                }
                                Qt.callLater(searchField.forceActiveFocus);
                            }
                        }

                        Behavior on color {
                            ColorAnimation {
                                duration: root.navigationStateDuration
                                easing.type: Easing.BezierSpline
                                easing.bezierCurve: Anims.expressiveEffects
                            }
                        }
                    }

                    Column {
                        id: childrenColumn
                        width: parent.width
                        spacing: Theme.spacingXXS
                        visible: categoryDelegate.modelData.children !== undefined && root.isCategoryExpanded(categoryDelegate.modelData.id)
                        clip: true

                        Repeater {
                            model: categoryDelegate.modelData.children || []

                            delegate: Rectangle {
                                id: childDelegate
                                required property int index
                                required property var modelData

                                readonly property bool isActive: root.currentIndex === modelData.tabIndex
                                readonly property bool isHighlighted: root.keyboardHighlightIndex === modelData.tabIndex

                                width: childrenColumn.width
                                height: Math.max(Theme.iconSize - 4, Theme.fontSizeSmall + 1) + Theme.spacingS * 2
                                radius: Theme.cornerRadius
                                visible: root.isItemVisible(modelData)
                                color: {
                                    if (isActive)
                                        return Theme.buttonBg;
                                    if (isHighlighted)
                                        return Theme.buttonHover;
                                    if (childMouseArea.containsMouse)
                                        return Theme.surfaceHover;
                                    return "transparent";
                                }

                                DankRipple {
                                    id: childRipple
                                    rippleColor: childDelegate.isActive ? Theme.buttonText : Theme.surfaceText
                                    cornerRadius: childDelegate.radius
                                    animationDuration: Anims.settingsNavigationRippleDuration
                                }

                                Row {
                                    id: childRowContent
                                    anchors.left: parent.left
                                    anchors.leftMargin: Theme.spacingL + Theme.spacingM
                                    anchors.verticalCenter: parent.verticalCenter
                                    spacing: Theme.spacingM

                                    DankIcon {
                                        name: childDelegate.modelData.icon || ""
                                        size: Theme.iconSize - 4
                                        color: childDelegate.isActive ? Theme.buttonText : Theme.surfaceVariantText
                                        anchors.verticalCenter: parent.verticalCenter
                                    }

                                    StyledText {
                                        text: childDelegate.modelData.text || ""
                                        font.pixelSize: Theme.fontSizeSmall + 1
                                        font.weight: childDelegate.isActive ? Font.Medium : Font.Normal
                                        color: childDelegate.isActive ? Theme.buttonText : Theme.surfaceText
                                        anchors.verticalCenter: parent.verticalCenter
                                    }
                                }

                                MouseArea {
                                    id: childMouseArea
                                    anchors.fill: parent
                                    hoverEnabled: true
                                    cursorShape: Qt.PointingHandCursor
                                    onPressed: mouse => childRipple.trigger(mouse.x, mouse.y)
                                    onClicked: {
                                        root.keyboardHighlightIndex = -1;
                                        root.tabChangeRequested(childDelegate.modelData.tabIndex);
                                        Qt.callLater(searchField.forceActiveFocus);
                                    }
                                }

                                Behavior on color {
                                    ColorAnimation {
                                        duration: root.navigationStateDuration
                                        easing.type: Easing.BezierSpline
                                        easing.bezierCurve: Anims.expressiveEffects
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
