// The Dock's pinned applications: reorder, remove, and add.
//
// The list was a sixteen-entry literal in Settings.qml, so changing what sits
// in the Dock meant editing a QML file and reloading the shell. It is a plain
// ordered list of desktop entry ids, stored in the shared settings file, which
// means it is covered by Restore defaults like everything else.
//
// Move up / move down rather than drag-and-drop. Dragging inside a Flickable
// that is itself inside a scrolling page is a genuinely hard interaction to get
// right, and it fails in a way the user reads as the app being broken; two
// buttons are unambiguous and keyboard-reachable.

import QtQuick
import Quickshell
import qs.config
import qs.services
import qs.widgets

Column {
    id: root

    spacing: 0

    readonly property var pinned: {
        const stored = DesktopPreferences.get("dockPinned");
        return Array.isArray(stored) ? stored : [];
    }

    // DesktopEntries populates asynchronously, so this must be read as a
    // binding rather than looked up inside one -- byId() called during
    // evaluation registers no dependency and answers from an empty list.
    readonly property var entriesById: {
        const index = {};
        for (const entry of DesktopEntries.applications.values)
            index[entry.id] = entry;
        return index;
    }

    function nameFor(id: string): string {
        const entry = root.entriesById[id];
        return entry ? entry.name : id;
    }

    function commit(next: var): void {
        DesktopPreferences.set("dockPinned", next);
    }

    function move(from: int, to: int): void {
        if (to < 0 || to >= root.pinned.length)
            return;
        const next = root.pinned.slice();
        const moved = next.splice(from, 1)[0];
        next.splice(to, 0, moved);
        root.commit(next);
    }

    function remove(index: int): void {
        const next = root.pinned.slice();
        next.splice(index, 1);
        root.commit(next);
    }

    function add(id: string): void {
        if (root.pinned.indexOf(id) >= 0)
            return;
        root.commit(root.pinned.concat([id]));
    }

    Repeater {
        model: root.pinned

        SettingRow {
            id: pin

            required property var modelData
            required property int index

            label: root.nameFor(pin.modelData)
            detail: pin.modelData
            divider: pin.index < root.pinned.length - 1
            controlWidth: 132

            Row {
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                spacing: 4

                SettingsButton {
                    text: "↑"
                    enabled: pin.index > 0
                    onClicked: root.move(pin.index, pin.index - 1)
                }
                SettingsButton {
                    text: "↓"
                    enabled: pin.index < root.pinned.length - 1
                    onClicked: root.move(pin.index, pin.index + 1)
                }
                SettingsButton {
                    text: "Unpin"
                    onClicked: root.remove(pin.index)
                }
            }
        }
    }

    SettingRow {
        visible: root.pinned.length === 0
        label: "Nothing is pinned"
        detail: "The Dock will only show running applications"
        divider: false
    }
}
