pragma ComponentBehavior: Bound

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

Item {
    id: root

    property var controller: null
    property bool hasQuery: false
    property var rows: []
    readonly property real bottomInset: Theme.spacingS

    signal itemRightClicked(int index, var item, real mouseX, real mouseY)

    function resetScroll() {
        mainListView.contentY = mainListView.originY;
    }

    function ensureVisible(flatIndex) {
        if (!controller || flatIndex < 0)
            return;
        for (let i = 0; i < rows.length; i++) {
            if ((rows[i]?.flatIndex ?? -1) === flatIndex) {
                mainListView.positionViewAtIndex(i, ListView.Contain);
                return;
            }
        }
    }

    function getSelectedItemPosition() {
        const fallback = mapToItem(null, width / 2, Math.min(height / 2, 56));
        if (!controller || controller.selectedFlatIndex < 0)
            return fallback;
        for (let i = 0; i < rows.length; i++) {
            if ((rows[i]?.flatIndex ?? -1) === controller.selectedFlatIndex) {
                const rowY = i * mainListView.rowHeight - mainListView.contentY + mainListView.originY;
                return mapToItem(null, width / 2, Math.max(28, Math.min(height - 28, rowY + mainListView.rowHeight / 2)));
            }
        }
        return fallback;
    }

    Connections {
        target: root.controller
        function onSelectedFlatIndexChanged() {
            if (root.controller?.keyboardNavigationActive)
                Qt.callLater(() => root.ensureVisible(root.controller.selectedFlatIndex));
        }
    }

    DankListView {
        id: mainListView
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.bottomMargin: root.bottomInset
        clip: true
        visible: root.rows.length > 0
        add: null

        readonly property int rowHeight: 64

        model: ScriptModel {
            values: root.rows
            objectProp: "_rowId"
        }

        delegate: Item {
            id: delegateRoot
            required property var modelData
            required property int index

            width: mainListView.width
            height: mainListView.rowHeight

            SpotlightResultRow {
                anchors.fill: parent
                anchors.leftMargin: Theme.spacingS
                anchors.rightMargin: Theme.spacingS
                anchors.topMargin: 3
                anchors.bottomMargin: 3
                item: delegateRoot.modelData?.item ?? null
                sectionTitle: delegateRoot.modelData?.sectionTitle ?? ""
                sectionIcon: delegateRoot.modelData?.sectionIcon ?? ""
                flatIndex: delegateRoot.modelData?.flatIndex ?? -1
                controller: root.controller
                isSelected: (delegateRoot.modelData?.flatIndex ?? -1) === root.controller?.selectedFlatIndex

                onClicked: {
                    if (root.controller && delegateRoot.modelData?.item)
                        root.controller.executeItem(delegateRoot.modelData.item);
                }

                onRightClicked: (mouseX, mouseY) => {
                    root.itemRightClicked(delegateRoot.modelData?.flatIndex ?? -1, delegateRoot.modelData?.item ?? null, mouseX, mouseY);
                }
            }
        }
    }

    Item {
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.bottom: parent.bottom
        anchors.bottomMargin: root.bottomInset
        visible: root.hasQuery && root.rows.length === 0

        Row {
            anchors.centerIn: parent
            spacing: Theme.spacingM

            Rectangle {
                width: 40
                height: 40
                radius: Theme.cornerRadius
                anchors.verticalCenter: parent.verticalCenter
                color: Theme.surfaceContainerHigh

                DankIcon {
                    anchors.centerIn: parent
                    name: root.controller?.isSearching || root.controller?.isFileSearching ? "search" : statusIcon()
                    size: 22
                    color: Theme.surfaceVariantText

                    function statusIcon() {
                        const mode = root.controller?.searchMode ?? "all";
                        if (mode === "files")
                            return "folder_open";
                        if (mode === "plugins")
                            return "extension";
                        if (mode === "apps")
                            return "apps";
                        return "search_off";
                    }
                }
            }

            Column {
                anchors.verticalCenter: parent.verticalCenter
                width: Math.min(420, root.width - 88)
                spacing: Theme.spacingXXS

                StyledText {
                    width: parent.width
                    text: statusTitle()
                    font.pixelSize: Theme.fontSizeMedium
                    font.weight: Font.Medium
                    color: Theme.surfaceText
                    elide: Text.ElideRight

                    function statusTitle() {
                        if (root.controller?.isSearching || root.controller?.isFileSearching)
                            return I18n.tr("Searching...");
                        if ((root.controller?.searchMode ?? "") === "files" && !DSearchService.dsearchAvailable)
                            return I18n.tr("File search unavailable");
                        if ((root.controller?.searchMode ?? "") === "files" && (root.controller?.searchQuery?.length ?? 0) < 2)
                            return I18n.tr("Keep typing");
                        return I18n.tr("No results");
                    }
                }

                StyledText {
                    width: parent.width
                    text: statusSubtitle()
                    font.pixelSize: Theme.fontSizeSmall
                    color: Theme.surfaceVariantText
                    maximumLineCount: 2
                    wrapMode: Text.WordWrap
                    elide: Text.ElideRight

                    function statusSubtitle() {
                        if ((root.controller?.searchMode ?? "") === "files" && !DSearchService.dsearchAvailable)
                            return I18n.tr("Install dsearch to search files.");
                        if ((root.controller?.searchMode ?? "") === "files" && (root.controller?.searchQuery?.length ?? 0) < 2)
                            return I18n.tr("Type at least 2 characters to search files.");
                        return I18n.tr("Try a different search or switch filters.");
                    }
                }
            }
        }
    }
}
