import QtQuick
import QtQuick.Layouts
import Quickshell
import Quickshell.Wayland
import Quickshell.Services.SystemTray
import Quickshell.Widgets

import "../../config" as Cfg
import "../../components"

ModuleChip {
    id: root

    property string barSide: "right"
    property bool expanded: false
    property bool manuallyExpanded: false

    readonly property bool effectiveExpanded: expanded || trayMenuPopup.popupOpen

    implicitWidth:  mainRow.width
    implicitHeight: Cfg.Config.barHeight

    readonly property color tmBg:        t.trayMenuBg
    readonly property color tmBorder:    t.trayMenuBorder
    readonly property color tmText:      t.trayMenuText
    readonly property color tmDim:       t.trayMenuDim
    readonly property color tmHover:     t.trayMenuHover
    readonly property color tmCheck:     t.trayMenuCheck
    readonly property color tmSeparator: t.trayMenuSeparator

    chipColor:         t.trayBg
    chipColorHovered:  t.trayBgHover
    chipBorderColor:   t.trayBorder
    chipBorderColorHovered: t.trayBorderHover
    popupOpen:         trayMenuPopup.popupOpen

    HoverHandler {
        onHoveredChanged: {
            if (!root.manuallyExpanded) {
                root.expanded = hovered;
            }
        }
    }

    Row {
        id: mainRow
        anchors.verticalCenter: parent.verticalCenter

        leftPadding:  root.effectiveExpanded && root.barSide === "right" ? 8 : 0
        rightPadding: root.effectiveExpanded && root.barSide === "left"  ? 8 : 0

        Behavior on leftPadding  { NumberAnimation { duration: 200; easing.type: Easing.OutCubic } }
        Behavior on rightPadding { NumberAnimation { duration: 200; easing.type: Easing.OutCubic } }

        layoutDirection: root.barSide === "left" ? Qt.LeftToRight : Qt.RightToLeft
        spacing: root.effectiveExpanded ? 4 : 0

        Behavior on spacing { NumberAnimation { duration: 180; easing.type: Easing.OutCubic } }

        Item {
            id: toggleArea
                width:  Cfg.Config.trayToggleSize
                height: Cfg.Config.trayToggleSize
                z: 10

                TapHandler {
                    onTapped: {
                        root.manuallyExpanded = !root.manuallyExpanded;
                        root.expanded = root.manuallyExpanded;
                    }
                }

                Text {
                    anchors.centerIn: parent
                    text: root.effectiveExpanded
                        ? (root.barSide === "left" ? "󰅁" : "󰅂")
                        : (root.barSide === "left" ? "󰅂" : "󰅁")
                    color: root.t.trayIcon
                    font.pixelSize: Cfg.Config.trayToggleSize * 0.55
                }
            }

            Row {
                id: iconsRow
                spacing: 6
                clip: true
                anchors.verticalCenter: parent.verticalCenter

                width: root.effectiveExpanded ? implicitWidth : 0
                opacity: root.effectiveExpanded ? 1 : 0

                Behavior on width { NumberAnimation { duration: 200; easing.type: Easing.OutCubic } }
                Behavior on opacity { NumberAnimation { duration: 150 } }

                Repeater {
                    model: SystemTray.items

                    delegate: MouseArea {
                        id: iconDelegate
                        required property SystemTrayItem modelData
                        property alias item: iconDelegate.modelData

                        implicitWidth:  Cfg.Config.trayIconSize
                        implicitHeight: Cfg.Config.trayIconSize
                        width:          Cfg.Config.trayIconSize
                        height:         Cfg.Config.trayIconSize

                        acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
                        hoverEnabled: true

                        onClicked: function(mouse) {
                            if (mouse.button === Qt.LeftButton) {
                                item.activate()
                            } else if (mouse.button === Qt.MiddleButton) {
                                item.secondaryActivate()
                            } else if (mouse.button === Qt.RightButton) {
                                if (item.hasMenu) {
                                    trayMenuPopup.open(item, iconDelegate)
                                }
                            }
                        }

                        onWheel: function(wheel) {
                            wheel.accepted = true
                            item.scroll(wheel.angleDelta.y / 120, false)
                        }

                        IconImage {
                            anchors.fill: parent
                            source: item.icon
                        }
                    }
                }
        }

    }




    PanelWindow {
        id: trayMenuPopup
        screen: root.targetScreen
        visible: false
        color: "transparent"

        property bool popupOpen: false
        property bool _pendingOpen: false
        property var activeTrayItem: null
        property var activeDelegate: null

        function open(item, delegate) {
            if (popupOpen) close()
            hideTimer.stop()
            _pendingOpen = false
            activeTrayItem = item
            activeDelegate = delegate
            rootMenuOpener.menu = item.menu
            visible = true


            if (menuCol.height > 0) {
                popupOpen = true
            } else {
                _pendingOpen = true
                openFallbackTimer.restart()
            }
        }

        function close() {
            _pendingOpen = false
            openFallbackTimer.stop()
            popupOpen = false
            hideTimer.restart()
        }




        Connections {
            target: menuCol
            function onHeightChanged() {
                if (trayMenuPopup._pendingOpen && menuCol.height > 0) {
                    trayMenuPopup._pendingOpen = false
                    openFallbackTimer.stop()
                    trayMenuPopup.popupOpen = true
                }
            }
        }


        Timer {
            id: openFallbackTimer
            interval: 400
            onTriggered: {
                if (trayMenuPopup._pendingOpen) {
                    trayMenuPopup._pendingOpen = false
                    trayMenuPopup.popupOpen = true
                }
            }
        }

        PopupHideTimer {
            id: hideTimer
            onTriggered: {
                trayMenuPopup.visible = false
                rootMenuOpener.menu = null
                trayMenuPopup.activeTrayItem = null
                trayMenuPopup.activeDelegate = null
            }
        }

        anchors { top: true; bottom: true; left: true; right: true }
        WlrLayershell.layer: WlrLayer.Top
        WlrLayershell.namespace: "main-shell-tray-menu"
        WlrLayershell.exclusiveZone: -1
        mask: popupOpen ? null : _trayMenuNoInput
        Region { id: _trayMenuNoInput }

        TapHandler { onTapped: trayMenuPopup.close() }

        QsMenuOpener { id: rootMenuOpener }

        Component {
            id: trayMenuItemComponent

            Item {
                id: menuItem
                required property var modelData
                readonly property bool isSep: modelData.isSeparator

                width: parent.width
                height: isSep ? 5 : 32

                Rectangle {
                    visible: isSep
                    anchors {
                        left: parent.left; right: parent.right
                        verticalCenter: parent.verticalCenter
                    }
                    anchors.leftMargin: 8; anchors.rightMargin: 8
                    height: 1
                    color: root.tmSeparator
                }

                Rectangle {
                    visible: !isSep
                    anchors.fill: parent
                    anchors.margins: 2
                    radius: 8
                    readonly property bool active: menuMouse.containsMouse
                        || (submenuCard.visible
                            && trayMenuPopup._submenuParentRef === menuItem)
                    color: active ? root.tmHover : "transparent"
                    Behavior on color { ColorAnimation { duration: 60 } }

                    RowLayout {
                        anchors.fill: parent
                        anchors.leftMargin: 8; anchors.rightMargin: 8
                        spacing: 8

                        Item {
                            Layout.preferredWidth: 16
                            Layout.preferredHeight: 16
                            visible: !isSep

                            Text {
                                anchors.centerIn: parent
                                visible: modelData.buttonType === QsMenuButtonType.CheckBox
                                    && modelData.checkState === Qt.Checked
                                text: "✓"; color: root.tmCheck
                                font.pixelSize: 14
                            }
                            Text {
                                anchors.centerIn: parent
                                visible: modelData.buttonType === QsMenuButtonType.RadioButton
                                    && modelData.checkState === Qt.Checked
                                text: "●"; color: root.tmCheck
                                font.pixelSize: 9
                            }
                            Text {
                                anchors.centerIn: parent
                                visible: modelData.buttonType === QsMenuButtonType.RadioButton
                                    && modelData.checkState !== Qt.Checked
                                text: "○"; color: root.tmDim
                                font.pixelSize: 11
                            }
                        }

                        Image {
                            visible: !isSep && modelData.icon !== ""
                            source: modelData.icon
                            width: 16; height: 16
                            sourceSize: Qt.size(16, 16)
                            fillMode: Image.PreserveAspectFit
                        }

                        Text {
                            text: modelData.text
                            color: modelData.enabled ? root.tmText : root.tmDim
                            font.pixelSize: 13
                            Layout.fillWidth: true
                            elide: Text.ElideRight
                        }

                        Text {
                            visible: !isSep && modelData.hasChildren
                            text: "▶"
                            color: root.tmDim
                            font.pixelSize: 9
                        }
                    }

                    MouseArea {
                        id: menuMouse
                        anchors.fill: parent
                        hoverEnabled: true
                        enabled: !isSep && modelData.enabled

                        onClicked: {
                            if (modelData.hasChildren) {
                                closeSubmenuTimer.stop()
                                submenuDelayTimer.itemRef = menuItem
                                submenuDelayTimer.restart()
                            } else {
                                modelData.triggered()
                                trayMenuPopup.close()
                            }
                        }
                        onEntered: {
                            if (modelData.hasChildren) {
                                closeSubmenuTimer.stop()
                                submenuDelayTimer.itemRef = menuItem
                                submenuDelayTimer.restart()
                            } else {
                                closeSubmenuTimer.stop()
                                submenuCard.visible = false
                            }
                        }
                        onExited: {
                            if (modelData.hasChildren)
                                closeSubmenuTimer.restart()
                        }
                    }
                }
            }
        }

        Item {
            id: menuCardWrapper
            readonly property int cardW: 220
            readonly property int pad:   10


            x: {
                if (!trayMenuPopup.activeDelegate)
                    return (parent.width - cardW) / 2
                var gp = trayMenuPopup.activeDelegate.mapToGlobal(0, 0)
                var cx = gp.x + trayMenuPopup.activeDelegate.width / 2
                return Math.max(pad,
                    Math.min(cx - cardW / 2, parent.width - cardW - pad))
            }

            width: cardW
            clip: true


            anchors.top: root.isTop ? parent.top : undefined
            anchors.bottom: root.isTop ? undefined : parent.bottom
            anchors.topMargin:    root.isTop ? (Cfg.Config.barHeight + root.barEdgePad + 8) : 0
            anchors.bottomMargin: root.isTop ? 0 : (Cfg.Config.barHeight + root.barEdgePad + 8)
            height: parent.height - Cfg.Config.barHeight - root.barEdgePad - 8

            PopupCard {
                id: menuCard
                popupOpen: trayMenuPopup.popupOpen
                isTop: root.isTop
                animEnabled: true
                height: menuCol.height + 12

                color: root.tmBg
                radius: Cfg.Config.popupRadius
                border.color: root.tmBorder
                border.width: Cfg.Config.popupBorderWidth

                Column {
                    id: menuCol
                    anchors { left: parent.left; right: parent.right; top: parent.top }
                    anchors.margins: 6
                    spacing: 0

                    Repeater {
                        model: rootMenuOpener.children
                        delegate: trayMenuItemComponent
                    }
                }
            }
        }


        property var _submenuParentRef: null

        QsMenuOpener { id: subMenuOpener }

        Timer {
            id: submenuDelayTimer
            interval: 250
            property var itemRef: null
            onTriggered: {
                if (!itemRef) return
                var entry = itemRef.modelData
                if (!entry || !entry.hasChildren) return
                subMenuOpener.menu = entry
                trayMenuPopup._submenuParentRef = itemRef
                submenuCard.visible = true
            }
        }

        Timer {
            id: closeSubmenuTimer
            interval: 300
            onTriggered: {
                if (!submenuCard.containsMouse) {
                    submenuCard.visible = false
                    subMenuOpener.menu = null
                    trayMenuPopup._submenuParentRef = null
                }
            }
        }


        Rectangle {
            id: submenuCard
            visible: false
            property bool containsMouse: false

            property int subW: Math.max(submenuCol.width, 180)

            x: {
                if (!trayMenuPopup._submenuParentRef) return 0
                var pItem = trayMenuPopup._submenuParentRef
                var gp = pItem.mapToGlobal(0, 0)
                var lp = trayMenuPopup.contentItem.mapFromGlobal(gp.x, gp.y)
                var fromLeft = lp.x + pItem.width + 4
                if (fromLeft + subW + 10 > trayMenuPopup.contentItem.width)
                    return Math.max(2, lp.x - subW - 4)
                return fromLeft
            }

            y: {
                if (!trayMenuPopup._submenuParentRef) return 0
                var pItem = trayMenuPopup._submenuParentRef
                var gp = pItem.mapToGlobal(0, 0)
                var lp = trayMenuPopup.contentItem.mapFromGlobal(gp.x, gp.y)
                return Math.max(2, lp.y - 2)
            }

            width: subW
            height: submenuCol.height + 12

            color: root.tmBg
            radius: Cfg.Config.popupRadius
            border.color: root.tmBorder
            border.width: Cfg.Config.popupBorderWidth

            HoverHandler {
                onHoveredChanged: {
                    submenuCard.containsMouse = hovered
                    if (!hovered)
                        closeSubmenuTimer.restart()
                }
            }

            Column {
                id: submenuCol
                anchors { left: parent.left; right: parent.right; top: parent.top }
                anchors.margins: 6
                spacing: 0

                Repeater {
                    model: subMenuOpener.children
                    delegate: trayMenuItemComponent
                }
            }
        }
    }
}
