import QtQuick
import Quickshell
import Quickshell.Services.SystemTray
import Quickshell.Widgets
import "../.."

Item {
    id: root
    width: parent ? parent.width : 1280
    height: parent ? parent.height : 820
    focus: true

    property ShellStateManager manager: null

    // ITEM/APPS-like layout constants
    property int menuTop: 140
    property int lineHeight: 79
    property int iconSize: 36
    property int textStartX: 239
    property int textRightPadding: 96
    property int visibleRows: Math.max(1, Math.floor((height - menuTop - 64) / lineHeight))

    property bool inSubmenu: false
    property int traySelection: 0
    property int submenuSelection: 0
    property int scrollOffset: 0
    property var menuStack: []
    property var currentMenuHandle: null
    property var submenuSourceTrayItem: null
    property int submenuPollTicks: 0

    readonly property int activeSelection: inSubmenu ? submenuSelection : traySelection

    ListModel {
        id: submenuData
    }

    QsMenuOpener {
        id: opener
        menu: root.currentMenuHandle
    }

    // Raw source entries from current DBus menu (hidden)
    Repeater {
        id: submenuSourceRepeater
        model: opener.children

        delegate: Item {
            visible: false
            width: 0
            height: 0
            property var entry: modelData
        }
    }

    Timer {
        id: submenuPollTimer
        interval: 120
        repeat: true
        running: false
        onTriggered: {
            if (!root.currentMenuHandle && root.submenuSourceTrayItem && root.submenuSourceTrayItem.menu)
                root.currentMenuHandle = root.submenuSourceTrayItem.menu;

            root.rebuildSubmenuData();
            root.submenuPollTicks = root.submenuPollTicks + 1;
            if (submenuData.count > 0 || root.submenuPollTicks >= 20)
                stop();
        }
    }

    function closeAll() {
        if (manager && manager.closeShell)
            manager.closeShell();
    }

    function clamp(v, lo, hi) {
        return Math.max(lo, Math.min(hi, v));
    }

    function trayCount() {
        return trayRepeater ? trayRepeater.count : 0;
    }

    function submenuCount() {
        return submenuData.count;
    }

    function currentCount() {
        return inSubmenu ? submenuCount() : trayCount();
    }

    function wrapIndex(i) {
        const length = currentCount();
        if (length === 0)
            return 0;
        return (i + length) % length;
    }

    function selectedTrayDelegate() {
        if (trayCount() <= 0)
            return null;
        return trayRepeater.itemAt(traySelection);
    }

    function selectedTrayItem() {
        const delegate = selectedTrayDelegate();
        return delegate ? delegate.trayItem : null;
    }

    function selectedMenuEntry() {
        if (submenuSelection < 0 || submenuSelection >= submenuData.count)
            return null;
        const row = submenuData.get(submenuSelection);
        return row ? row.entry : null;
    }

    function normalizeSelection() {
        const length = currentCount();
        if (length <= 0) {
            if (inSubmenu)
                submenuSelection = 0;
            else
                traySelection = 0;
            scrollOffset = 0;
            return;
        }

        if (inSubmenu)
            submenuSelection = clamp(submenuSelection, 0, length - 1);
        else
            traySelection = clamp(traySelection, 0, length - 1);

        const currentSelection = activeSelection;
        const maxOffset = Math.max(0, length - visibleRows);

        if (currentSelection < scrollOffset)
            scrollOffset = currentSelection;
        else if (currentSelection >= scrollOffset + visibleRows)
            scrollOffset = Math.max(0, currentSelection - visibleRows + 1);

        scrollOffset = clamp(scrollOffset, 0, maxOffset);
    }

    function rebuildSubmenuData() {
        submenuData.clear();

        const count = submenuSourceRepeater ? submenuSourceRepeater.count : 0;
        for (let i = 0; i < count; i++) {
            const sourceItem = submenuSourceRepeater.itemAt(i);
            const entry = sourceItem ? sourceItem.entry : null;
            if (!entry || entry.isSeparator)
                continue;

            submenuData.append({
                entry: entry
            });
        }

        submenuSelection = clamp(submenuSelection, 0, Math.max(0, submenuData.count - 1));
        normalizeSelection();
    }

    function enterSubmenu(menuHandle) {
        currentMenuHandle = menuHandle;
        inSubmenu = true;
        submenuSelection = 0;
        scrollOffset = 0;
        submenuData.clear();
        submenuPollTicks = 0;
        Qt.callLater(function () {
            rebuildSubmenuData();
            submenuPollTimer.restart();
        });
    }

    function openSelectedTraySubmenu() {
        const trayItem = selectedTrayItem();
        if (!trayItem)
            return;

        if (!trayItem.hasMenu) {
            trayItem.activate();
            closeAll();
            return;
        }

        menuStack = [];
        submenuSourceTrayItem = trayItem;
        enterSubmenu(trayItem.menu);
    }

    function triggerSelectedSubmenuEntry() {
        const entry = selectedMenuEntry();
        if (!entry)
            return;

        if (entry.hasChildren) {
            const stackCopy = menuStack.slice(0);
            stackCopy.push(currentMenuHandle);
            menuStack = stackCopy;
            submenuSourceTrayItem = null;
            enterSubmenu(entry);
            return;
        }

        entry.triggered();
        closeAll();
    }

    function backAction() {
        if (inSubmenu) {
            if (menuStack.length > 0) {
                const stackCopy = menuStack.slice(0);
                const parentHandle = stackCopy.pop();
                menuStack = stackCopy;
                submenuSourceTrayItem = null;
                enterSubmenu(parentHandle);
            } else {
                inSubmenu = false;
                currentMenuHandle = null;
                submenuSourceTrayItem = null;
                submenuData.clear();
                submenuPollTimer.stop();
                scrollOffset = 0;
                normalizeSelection();
            }
            return;
        }

        if (manager && manager.closePowerMenu)
            manager.closePowerMenu();
    }

    function resolveTrayIconSource(iconValue) {
        const normalized = String(iconValue || "").trim();
        if (normalized.length === 0)
            return "";
        if (normalized.indexOf("/") >= 0 || normalized.indexOf("file://") === 0)
            return normalized;
        return String(Quickshell.iconPath(normalized, true) || "");
    }

    function handleKey(key) {
        switch (key) {
        case Qt.Key_Up:
            if (inSubmenu)
                submenuSelection = wrapIndex(submenuSelection - 1);
            else
                traySelection = wrapIndex(traySelection - 1);
            normalizeSelection();
            return true;
        case Qt.Key_Down:
            if (inSubmenu)
                submenuSelection = wrapIndex(submenuSelection + 1);
            else
                traySelection = wrapIndex(traySelection + 1);
            normalizeSelection();
            return true;
        case Qt.Key_Z:
        case Qt.Key_Return:
        case Qt.Key_Enter:
            if (inSubmenu)
                triggerSelectedSubmenuEntry();
            else
                openSelectedTraySubmenu();
            return true;
        case Qt.Key_X:
        case Qt.Key_Shift:
        case Qt.Key_Escape:
            backAction();
            return true;
        }

        return false;
    }

    Connections {
        target: manager
        ignoreUnknownSignals: true
        function onPowerMenuOpened() {
            root.inSubmenu = false;
            root.currentMenuHandle = null;
            root.submenuSourceTrayItem = null;
            root.menuStack = [];
            root.submenuPollTicks = 0;
            submenuPollTimer.stop();
            submenuData.clear();
            root.scrollOffset = 0;
            root.traySelection = 0;
            root.submenuSelection = 0;
            root.normalizeSelection();
        }
    }

    Connections {
        target: SystemTray.items
        ignoreUnknownSignals: true
        function onCountChanged() {
            root.normalizeSelection();
        }
        function onModelReset() {
            root.normalizeSelection();
        }
        function onRowsInserted() {
            root.normalizeSelection();
        }
        function onRowsRemoved() {
            root.normalizeSelection();
        }
    }

    Connections {
        target: opener.children
        ignoreUnknownSignals: true
        function onCountChanged() {
            root.rebuildSubmenuData();
        }
        function onModelReset() {
            root.rebuildSubmenuData();
        }
        function onRowsInserted() {
            root.rebuildSubmenuData();
        }
        function onRowsRemoved() {
            root.rebuildSubmenuData();
        }
    }

    Text {
        text: inSubmenu ? "OPTIONS" : "POWER"
        font.family: "8bitoperator JVE"
        font.pixelSize: 71
        renderType: Text.NativeRendering
        font.hintingPreference: Font.PreferNoHinting
        smooth: false
        antialiasing: false
        anchors.horizontalCenter: parent.horizontalCenter
        color: "#ffffff"
        y: 32
    }

    Repeater {
        id: trayRepeater
        model: SystemTray.items

        delegate: Item {
            width: root.width
            height: root.lineHeight
            x: 0
            y: root.menuTop + (index - root.scrollOffset) * root.lineHeight
            visible: !root.inSubmenu && index >= root.scrollOffset && index < root.scrollOffset + root.visibleRows

            property var trayItem: modelData
            readonly property string trayIconSource: root.resolveTrayIconSource(trayItem ? trayItem.icon : "")

            Text {
                x: root.textStartX
                y: 0
                text: trayItem && trayItem.tooltipTitle ? trayItem.tooltipTitle : (trayItem ? trayItem.title : "")
                width: root.width - root.textStartX - root.textRightPadding
                font.family: "8bitoperator JVE"
                font.pixelSize: 71
                font.letterSpacing: 1
                renderType: Text.NativeRendering
                font.hintingPreference: Font.PreferNoHinting
                smooth: false
                antialiasing: false
                wrapMode: Text.NoWrap
                elide: Text.ElideRight
                color: root.activeSelection == index ? "#fefe00" : "#ffffff"
            }

            IconImage {
                id: trayIcon
                x: 182
                y: 8 + 14
                implicitSize: root.iconSize
                source: trayIconSource
                asynchronous: true
            }

            Image {
                source: "../QuickSettings/soul.png"
                width: 36
                height: 36
                x: trayIcon.x
                y: trayIcon.y
                opacity: 0.7
                visible: root.activeSelection == index
            }

            MouseArea {
                anchors.fill: parent
                hoverEnabled: true
                onEntered: {
                    root.traySelection = index;
                    root.normalizeSelection();
                }
                onClicked: {
                    root.traySelection = index;
                    root.normalizeSelection();
                    root.openSelectedTraySubmenu();
                }
                onWheel: function (wheel) {
                    if (!trayItem)
                        return;
                    const horizontal = Math.abs(wheel.angleDelta.x) > Math.abs(wheel.angleDelta.y);
                    const delta = horizontal ? wheel.angleDelta.x : wheel.angleDelta.y;
                    trayItem.scroll(delta, horizontal);
                    wheel.accepted = true;
                }
            }
        }
    }

    Repeater {
        id: submenuRepeater
        model: submenuData

        delegate: Item {
            property var entry: model.entry
            width: root.width
            height: root.lineHeight
            x: 0
            y: root.menuTop + (index - root.scrollOffset) * root.lineHeight
            visible: root.inSubmenu && index >= root.scrollOffset && index < root.scrollOffset + root.visibleRows

            Text {
                x: root.textStartX
                y: 0
                width: root.width - root.textStartX - root.textRightPadding
                text: {
                    if (!entry)
                        return "";

                    let prefix = "";
                    if (entry.buttonType === QsMenuButtonType.CheckBox)
                        prefix = entry.checkState === Qt.Checked ? "[x] " : "[ ] ";
                    else if (entry.buttonType === QsMenuButtonType.RadioButton)
                        prefix = entry.checkState === Qt.Checked ? "(x) " : "( ) ";

                    return prefix + String(entry.text || "") + (entry.hasChildren ? " >" : "");
                }
                font.family: "8bitoperator JVE"
                font.pixelSize: 71
                font.letterSpacing: 1
                renderType: Text.NativeRendering
                font.hintingPreference: Font.PreferNoHinting
                smooth: false
                antialiasing: false
                wrapMode: Text.NoWrap
                elide: Text.ElideRight
                color: root.activeSelection == index ? "#fefe00" : "#ffffff"
            }

            Image {
                source: "../QuickSettings/soul.png"
                width: 36
                height: 36
                x: 182
                y: 8 + 14
                opacity: 0.7
                visible: root.activeSelection == index
            }

            MouseArea {
                anchors.fill: parent
                hoverEnabled: true
                onEntered: {
                    root.submenuSelection = index;
                    root.normalizeSelection();
                }
                onClicked: {
                    root.submenuSelection = index;
                    root.normalizeSelection();
                    root.triggerSelectedSubmenuEntry();
                }
            }
        }
    }

    WheelHandler {
        acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad
        onWheel: function (event) {
            const count = root.currentCount();
            if (count <= 0)
                return;

            const delta = event.angleDelta.y > 0 ? -1 : 1;
            if (root.inSubmenu)
                root.submenuSelection = root.wrapIndex(root.submenuSelection + delta);
            else
                root.traySelection = root.wrapIndex(root.traySelection + delta);

            root.normalizeSelection();
            event.accepted = true;
        }
    }

    Text {
        visible: !root.inSubmenu && trayCount() === 0
        text: "NO TRAY ITEMS"
        font.family: "8bitoperator JVE"
        font.pixelSize: 54
        font.letterSpacing: 1
        renderType: Text.NativeRendering
        font.hintingPreference: Font.PreferNoHinting
        smooth: false
        antialiasing: false
        color: "#ffffff"
        anchors.horizontalCenter: parent.horizontalCenter
        y: 302
    }

    Text {
        visible: root.inSubmenu && !submenuPollTimer.running && submenuCount() === 0
        text: "NO OPTIONS"
        font.family: "8bitoperator JVE"
        font.pixelSize: 54
        font.letterSpacing: 1
        renderType: Text.NativeRendering
        font.hintingPreference: Font.PreferNoHinting
        smooth: false
        antialiasing: false
        color: "#ffffff"
        anchors.horizontalCenter: parent.horizontalCenter
        y: 302
    }

    Component.onCompleted: normalizeSelection()
}
