// SPDX-FileCopyrightText: 2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later

import QtQuick
import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Effects
import QtQuick.Shapes 1.8

import org.kde.kirigami as Kirigami

import org.kde.plasma.plasmoid 2.0
import org.kde.plasma.components 3.0 as PlasmaComponents

import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.state as MobileShellState
import org.kde.plasma.private.mobileshell.windowplugin as WindowPlugin
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.plasma.private.mobileshell.gamingshellplugin as GamingShell

import org.kde.layershell 1.0 as LayerShell
import org.kde.plasma.private.sessions 2.0
import org.kde.coreaddons as KCoreAddons
import org.kde.kcmutils as KCM
import org.kde.kirigamiaddons.components as KirigamiAddonsComponents

import plasma.applet.org.kde.plasma.mobile.homescreen.folio as Folio

import "./gaming"

import "./private"

ContainmentItem {
    id: root
    property var folio: root.plasmoid
    readonly property int shortAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.EffectsFast)

    // Tracks whether the Game Center grid is visible within gaming mode.
    // If gaming mode is already enabled at startup, open it immediately so
    // the user is never left without controls.
    property bool gameCenterOpen: ShellSettings.Settings.gamingModeEnabled
    property bool showGameCenterHint: false

    // State saved when gaming mode activates, restored when it deactivates
    property string _savedPowerProfile: ""
    property bool _savedDnd: false
    property bool _gamingSessionActive: false

    function _applyGamingModeState(enabled) {
        root.gameCenterOpen = enabled
        GamingShell.GamepadManager.active = enabled

        if (enabled === root._gamingSessionActive) {
            return
        }

        if (enabled) {
            // Save current state and apply gaming optimizations
            root._savedDnd = MobileShellState.ShellDBusClient.doNotDisturb
            MobileShellState.ShellDBusClient.doNotDisturb = true

            if (GamingShell.PowerProfileControl.available) {
                root._savedPowerProfile = GamingShell.PowerProfileControl.activeProfile
                GamingShell.PowerProfileControl.activeProfile = "performance"
            }

            GamingShell.GameModeControl.requestStart()
            root._gamingSessionActive = true
        } else {
            // Restore previous state
            MobileShellState.ShellDBusClient.doNotDisturb = root._savedDnd

            if (GamingShell.PowerProfileControl.available && root._savedPowerProfile.length > 0) {
                GamingShell.PowerProfileControl.activeProfile = root._savedPowerProfile
            }

            GamingShell.GameModeControl.requestEnd()
            root._gamingSessionActive = false
        }
    }

    Timer {
        id: gameCenterHintTimer
        interval: 2600
        onTriggered: root.showGameCenterHint = false
    }

    Connections {
        target: ShellSettings.Settings
        function onGamingModeEnabledChanged() {
            root._applyGamingModeState(ShellSettings.Settings.gamingModeEnabled)
        }
    }

    // Gamepad Guide button toggles Game Center overlay
    Connections {
        target: GamingShell.GamepadManager
        enabled: ShellSettings.Settings.gamingModeEnabled
        function onButtonPressed(button, gamepadIndex) {
            if (button === GamingShell.GamepadManager.ButtonGuide) {
                root.gameCenterOpen = !root.gameCenterOpen
            }
        }
    }

    Component.onCompleted: {
        root._applyGamingModeState(ShellSettings.Settings.gamingModeEnabled)
        folio.FolioSettings.load();
        folio.FavouritesModel.load();
        folio.PageListModel.load();
    }

    property MobileShell.MaskManager maskManager: MobileShell.MaskManager {
        height: root.height
        width: root.width
    }

    property MobileShell.MaskManager frontMaskManager: MobileShell.MaskManager {
        height: root.height
        width: root.width
    }

    // wallpaper blur layer
    MobileShell.BlurEffect {
        id: wallpaperBlur
        active: folio.FolioSettings.wallpaperBlurEffect > 0
        anchors.fill: parent
        sourceLayer: Plasmoid.wallpaperGraphicsObject
        maskSourceLayer: folio.FolioSettings.wallpaperBlurEffect > 1 ? maskManager.maskLayer : null

        fullBlur: Math.min(1,
                           Math.max(
                               1 - homeScreen.contentOpacity,
                               // Convergence: no blur for popup drawer
                               ShellSettings.Settings.convergenceModeEnabled ? 0 : folio.HomeScreenState.appDrawerOpenProgress * 2,
                               folio.HomeScreenState.searchWidgetOpenProgress * 1.5, // blur faster during swipe
                               folio.HomeScreenState.folderOpenProgress
                           )
        )
    }

    WindowPlugin.WindowMaximizedTracker {
        id: windowMaximizedTracker
        screenGeometry: Plasmoid.containment.screenGeometry
    }

    // In gaming mode, reopen Game Center when the last window goes away
    // so the user is never stranded on a bare wallpaper.
    Connections {
        target: windowMaximizedTracker
        enabled: ShellSettings.Settings.gamingModeEnabled
        function onShowingWindowChanged() {
            if (!windowMaximizedTracker.showingWindow && !root.gameCenterOpen) {
                root.gameCenterOpen = true
            }
        }
    }

    // Close app drawer when a new window appears
    Connections {
        target: WindowPlugin.WindowUtil
        function onWindowCreated() {
            if (folio.HomeScreenState.viewState === Folio.HomeScreenState.AppDrawerView) {
                folio.HomeScreenState.closeAppDrawer();
            }
        }
    }

    function homeAction() {
        const isInWindow = (!WindowPlugin.WindowUtil.isShowingDesktop && windowMaximizedTracker.showingWindow);

        // Always close action drawer
        if (MobileShellState.ShellDBusClient.isActionDrawerOpen) {
            MobileShellState.ShellDBusClient.closeActionDrawer();
        }

        if (ShellSettings.Settings.gamingModeEnabled) {
            // In gaming mode Home/Menu should reopen the Game Center overlay.
            root.gameCenterOpen = true;
            return;
        }

        if (ShellSettings.Settings.convergenceModeEnabled) {
            // Convergence: toggle the app drawer as a layer-shell overlay
            // without disturbing open windows.
            switch (folio.HomeScreenState.viewState) {
                case Folio.HomeScreenState.AppDrawerView:
                    folio.HomeScreenState.closeAppDrawer();
                    break;
                case Folio.HomeScreenState.FolderView:
                    folio.HomeScreenState.closeFolder();
                    break;
                case Folio.HomeScreenState.SearchWidgetView:
                    folio.HomeScreenState.closeSearchWidget();
                    break;
                case Folio.HomeScreenState.SettingsView:
                    folio.HomeScreenState.closeSettingsView();
                    break;
                default:
                    folio.HomeScreenState.openAppDrawer();
                    break;
            }
            return;
        }

        if (isInWindow) {
            folio.HomeScreenState.closeFolder();
            folio.HomeScreenState.closeSearchWidget();
            folio.HomeScreenState.closeAppDrawer();
            folio.HomeScreenState.goToPage(0, false);

            WindowPlugin.WindowUtil.minimizeAll();

            // Always ensure settings view is closed
            if (folio.HomeScreenState.viewState == Folio.HomeScreenState.SettingsView) {
                folio.HomeScreenState.closeSettingsView();
            }

        } else { // If we are already on the homescreen
            switch (folio.HomeScreenState.viewState) {
                case Folio.HomeScreenState.PageView:
                    if (folio.HomeScreenState.currentPage === 0) {
                        folio.HomeScreenState.openAppDrawer();
                    } else {
                        folio.HomeScreenState.goToPage(0, false);
                    }
                    break;
                case Folio.HomeScreenState.AppDrawerView:
                    folio.HomeScreenState.closeAppDrawer();
                    break;
                case Folio.HomeScreenState.SearchWidgetView:
                    folio.HomeScreenState.closeSearchWidget();
                    break;
                case Folio.HomeScreenState.FolderView:
                    folio.HomeScreenState.closeFolder();
                    break;
                case Folio.HomeScreenState.SettingsView:
                    folio.HomeScreenState.closeSettingsView();
                    break;
            }
        }
    }

    Plasmoid.onActivated: homeAction()

    Rectangle {
        id: appDrawerBackground
        anchors.fill: parent
        // Convergence: no scrim (popup has own background); mobile: dark scrim
        color: ShellSettings.Settings.convergenceModeEnabled
            ? "transparent"
            : Qt.rgba(0, 0, 0, 0.6)

        opacity: folio.HomeScreenState.appDrawerOpenProgress
    }

    Rectangle {
        id: searchWidgetBackground
        anchors.fill: parent
        color: Qt.rgba(0, 0, 0, 0.3)

        opacity: folio.HomeScreenState.searchWidgetOpenProgress
    }

    Rectangle {
        id: settingsViewBackground
        anchors.fill: parent
        color: Qt.rgba(0, 0, 0, 0.3)

        opacity: folio.HomeScreenState.settingsOpenProgress
    }

    // Dock overlay window — renders the favourites bar above application
    // windows in convergence mode.  LayerTop sits above normal windows but
    // below LayerOverlay (notifications, volume OSD).  The exclusive zone
    // that reserves screen space is handled by the dockSpaceReserver in the
    // task panel containment; this window only provides the visible dock.
    Window {
        id: dockOverlay
        readonly property bool active: ShellSettings.Settings.convergenceModeEnabled
                                       && !ShellSettings.Settings.gamingModeEnabled
                                       && !folio.overviewActive

        visible: active
        opacity: active ? 1 : 0
        color: "transparent"
        width: Screen.width
        height: MobileShell.Constants.convergenceDockHeight

        LayerShell.Window.scope: "dock-overlay"
        LayerShell.Window.layer: LayerShell.Window.LayerTop
        LayerShell.Window.anchors: LayerShell.Window.AnchorBottom | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
        LayerShell.Window.exclusionZone: shouldReserveSpace ? dockHeight : -1
        LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityOnDemand

        // Auto-hide: slide dock content off-screen when a window is
        // maximized.  The reveal strip at the screen edge brings it back.
        property real dockOffset: 0
        readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight
        readonly property int dockAnimationDuration: MobileShell.Motion.duration(MobileShell.Motion.SpatialDefault)
        readonly property int dockFadeDuration: MobileShell.Motion.duration(MobileShell.Motion.EffectsFast)

        // Height of the input-receive strip kept at the screen edge when
        // the dock is hidden.  Matches the navigation panel convention.
        readonly property real revealStripHeight: MobileShell.Constants.convergenceDockRevealHeight

        // True once the hover-reveal timer fires; cleared on hover-exit.
        property bool hoverRevealing: false

        readonly property bool shouldHide: ShellSettings.Settings.autoHidePanelsEnabled
                                              && windowMaximizedTracker.showingWindow && !hoverRevealing
        readonly property bool shouldReserveSpace: ShellSettings.Settings.autoHidePanelsEnabled
                                                   && windowMaximizedTracker.showingWindow && hoverRevealing

        function updateInputRegion() {
            if (shouldHide && dockOffset >= dockHeight) {
                MobileShell.ShellUtil.setInputRegion(dockOverlay,
                    Qt.rect(0, dockOverlay.height - revealStripHeight,
                            dockOverlay.width, revealStripHeight))
            } else {
                MobileShell.ShellUtil.setInputRegion(dockOverlay, Qt.rect(0, 0, 0, 0))
            }
        }

        onActiveChanged: {
            hoverRevealTimer.stop()
            hoverRevealing = false
            dockOffset = shouldHide ? dockHeight : 0
            updateInputRegion()
        }

        onShouldHideChanged: {
            if (shouldHide) {
                dockOffset = dockHeight
            } else {
                dockOffset = 0
            }
            updateInputRegion()
        }

        // Narrow the input region to a strip at the screen edge when hidden
        // so that app controls near the bottom edge are not accidentally
        // intercepted.  Mirrors the same pattern used by NavigationPanel.
        onDockOffsetChanged: {
            updateInputRegion()
        }
        onWidthChanged: updateInputRegion()
        onHeightChanged: updateInputRegion()

        // Delay reveal briefly so a quick edge graze does not pop the
        // dock up mid-interaction with the underlying application.
        Timer {
            id: hoverRevealTimer
            interval: Kirigami.Units.shortDuration
            repeat: false
            onTriggered: dockOverlay.hoverRevealing = true
        }

        HoverHandler {
            id: dockHoverHandler
            onHoveredChanged: {
                if (hovered) {
                    hoverRevealTimer.start()
                } else {
                    hoverRevealTimer.stop()
                    dockOverlay.hoverRevealing = false
                }
            }
        }

        Behavior on dockOffset {
            MobileShell.MotionNumberAnimation {
                type: MobileShell.Motion.SpatialDefault
                duration: dockOverlay.dockAnimationDuration
            }
        }

        Behavior on opacity {
            MobileShell.MotionNumberAnimation { type: MobileShell.Motion.EffectsFast; duration: dockOverlay.dockFadeDuration }
        }

        Rectangle {
            anchors.fill: parent
            visible: !dockOverlay.shouldHide || dockOverlay.dockOffset < dockOverlay.dockHeight
            Kirigami.Theme.inherit: false
            Kirigami.Theme.colorSet: Kirigami.Theme.Window
            color: Kirigami.Theme.backgroundColor
        }

        FavouritesBar {
            id: dockOverlayBar
            anchors.fill: parent
            folio: root.folio
            maskManager: root.maskManager
            homeScreen: folioHomeScreen
            suppressRunningTasks: runningAppsPanel.visible
            transform: Translate { y: dockOverlay.dockOffset }
            // Dock is an opaque panel — use Window colorset so all content
            // (labels, hover highlights, icon tints) follows the system theme
            // instead of the containment's Complementary wallpaper context.
            Kirigami.Theme.inherit: false
            Kirigami.Theme.colorSet: Kirigami.Theme.Window
        }
    }

    // App-drawer overlay — renders the popup drawer above application
    // windows in convergence mode.  Same pattern as the dock overlay:
    // a fullscreen layer-shell surface at LayerTop so that it appears
    // over normal windows without minimizing them.
    Window {
        id: drawerOverlay
        visible: ShellSettings.Settings.convergenceModeEnabled
                 && !ShellSettings.Settings.gamingModeEnabled
                 && folio.HomeScreenState.appDrawerOpenProgress > 0
        color: "transparent"
        width: Screen.width
        height: Screen.height

        LayerShell.Window.scope: "drawer-overlay"
        LayerShell.Window.layer: LayerShell.Window.LayerTop
        LayerShell.Window.anchors: LayerShell.Window.AnchorTop | LayerShell.Window.AnchorBottom
                                   | LayerShell.Window.AnchorLeft | LayerShell.Window.AnchorRight
        LayerShell.Window.exclusionZone: -1
        LayerShell.Window.keyboardInteractivity: LayerShell.Window.KeyboardInteractivityOnDemand

        // Click outside the popup to dismiss
        MouseArea {
            anchors.fill: parent
            onClicked: folio.HomeScreenState.closeAppDrawer()
        }

        AppDrawer {
            id: overlayDrawer
            folio: root.folio
            homeScreen: folioHomeScreen

            readonly property real popupWidth: Math.min(Kirigami.Units.gridUnit * 28, parent.width * 0.5)
            readonly property real dockHeight: MobileShell.Constants.convergenceDockHeight
            readonly property real sideInset: MobileShell.Constants.convergenceWorkspaceFrameThickness
            readonly property real connectedPanelGap: 0
            readonly property real popupTopY: MobileShell.Constants.topPanelHeight
                + MobileShell.Constants.convergenceWorkspaceFrameThickness
            readonly property real popupBottomY: parent.height
                - dockHeight
                - MobileShell.Constants.convergenceWorkspaceFrameThickness
            readonly property real popupHeight: Math.max(0, popupBottomY - popupTopY)

            width: popupWidth
            height: popupHeight

            opacity: folio.HomeScreenState.appDrawerOpenProgress < 0.5
                ? 0 : (folio.HomeScreenState.appDrawerOpenProgress - 0.5) * 2

            property real animationY: (1 - folio.HomeScreenState.appDrawerOpenProgress) * (Kirigami.Units.gridUnit * 2)

            x: sideInset
            y: (opacity > 0)
                ? popupTopY + animationY
                : parent.height

            headerHeight: Math.round(Kirigami.Units.gridUnit * 3)
            headerItem: AppDrawerHeader {
                id: overlayDrawerHeader
                folio: root.folio
                onReleaseFocusRequested: overlayDrawer.forceActiveFocus()
            }

            Keys.onPressed: (event) => {
                if (event.text.trim().length > 0) {
                    overlayDrawerHeader.addSearchText(event.text);
                    overlayDrawerHeader.forceActiveFocus();
                    event.accepted = true;
                } else if (event.key === Qt.Key_Left || event.key === Qt.Key_Right
                           || event.key === Qt.Key_Up || event.key === Qt.Key_Down) {
                    overlayDrawerHeader.forceActiveFocus();
                    event.accepted = true;
                }
            }

            Connections {
                target: folio.HomeScreenState

                function onAppDrawerOpened() {
                    folio.ApplicationListSearchModel.categoryFilter = ""
                    overlayDrawer.forceActiveFocus()
                }
            }
        }

        CategoryPanel {
            id: categoryPanel
            folio: root.folio

            width: Kirigami.Units.gridUnit * 9
            height: overlayDrawer.popupHeight
            x: overlayDrawer.x + overlayDrawer.width + overlayDrawer.connectedPanelGap
            y: overlayDrawer.y
            opacity: overlayDrawer.opacity

            onCategorySelected: (catId) => {
                folio.ApplicationListSearchModel.categoryFilter = catId
                overlayDrawerHeader.clearSearchText()
            }
        }

        Rectangle {
            id: powerPanel

            // Width: just enough for one icon button + side margins
            readonly property real tileSize: Kirigami.Units.iconSizes.medium + 2 * Kirigami.Units.largeSpacing

            width: tileSize
            height: overlayDrawer.popupHeight
            x: runningAppsPanel.visible
                ? runningAppsPanel.x + runningAppsPanel.width + overlayDrawer.connectedPanelGap
                : categoryPanel.x + categoryPanel.width + overlayDrawer.connectedPanelGap
            y: overlayDrawer.y
            opacity: overlayDrawer.opacity
            radius: 0
            color: Kirigami.Theme.backgroundColor

            MouseArea {
                anchors.fill: parent
            }

            KCoreAddons.KUser {
                id: kuser
            }

            SessionManagement {
                id: powerSession
            }

            // Close button anchored to top — smaller than power icons
            Rectangle {
                id: closeButton
                anchors.top: parent.top
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.margins: Kirigami.Units.smallSpacing
                height: Kirigami.Units.iconSizes.smallMedium + 2 * Kirigami.Units.smallSpacing
                radius: Kirigami.Units.cornerRadius
                color: closeArea.containsPress
                    ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.2)
                    : closeArea.containsMouse
                        ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
                        : "transparent"
                Kirigami.Icon {
                    anchors.centerIn: parent
                    width: Kirigami.Units.iconSizes.smallMedium
                    height: width
                    source: "window-close-symbolic"
                    active: closeArea.containsMouse
                    isMask: true
                    color: Kirigami.Theme.textColor
                }
                PlasmaComponents.ToolTip {
                    text: i18n("Close")
                    visible: closeArea.containsMouse
                }
                MouseArea {
                    id: closeArea
                    anchors.fill: parent
                    hoverEnabled: true
                    cursorShape: Qt.PointingHandCursor
                    onClicked: folio.HomeScreenState.closeAppDrawer()
                }
            }

            // Separator below close button
            Rectangle {
                anchors.top: closeButton.bottom
                anchors.topMargin: Kirigami.Units.smallSpacing
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.leftMargin: Kirigami.Units.smallSpacing
                anchors.rightMargin: Kirigami.Units.smallSpacing
                height: 1
                color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.15)
            }

            // Power buttons centred vertically in the panel
            Column {
                id: powerColumn
                anchors.verticalCenter: parent.verticalCenter
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.margins: Kirigami.Units.smallSpacing
                spacing: Kirigami.Units.smallSpacing

                Rectangle {
                    width: parent.width
                    height: width
                    radius: Kirigami.Units.cornerRadius
                    color: lockArea.containsPress
                        ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.2)
                        : lockArea.containsMouse
                            ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
                            : "transparent"
                    Kirigami.Icon {
                        anchors.centerIn: parent
                        width: Kirigami.Units.iconSizes.medium
                        height: width
                        source: "system-lock-screen"
                        active: lockArea.containsMouse
                        isMask: true
                        color: Kirigami.Theme.textColor
                    }
                    PlasmaComponents.ToolTip {
                        text: i18n("Lock Screen")
                        visible: lockArea.containsMouse
                    }
                    MouseArea {
                        id: lockArea
                        anchors.fill: parent
                        hoverEnabled: true
                        cursorShape: Qt.PointingHandCursor
                        onClicked: {
                            powerSession.lock()
                            folio.HomeScreenState.closeAppDrawer()
                        }
                    }
                }

                Rectangle {
                    width: parent.width
                    height: width
                    radius: Kirigami.Units.cornerRadius
                    color: rebootArea.containsPress
                        ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.2)
                        : rebootArea.containsMouse
                            ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
                            : "transparent"
                    Kirigami.Icon {
                        anchors.centerIn: parent
                        width: Kirigami.Units.iconSizes.medium
                        height: width
                        source: "system-reboot"
                        active: rebootArea.containsMouse
                        isMask: true
                        color: Kirigami.Theme.textColor
                    }
                    PlasmaComponents.ToolTip {
                        text: i18n("Restart")
                        visible: rebootArea.containsMouse
                    }
                    MouseArea {
                        id: rebootArea
                        anchors.fill: parent
                        hoverEnabled: true
                        cursorShape: Qt.PointingHandCursor
                        onClicked: {
                            folio.HomeScreenState.closeAppDrawer()
                            powerSession.requestReboot()
                        }
                    }
                }

                Rectangle {
                    width: parent.width
                    height: width
                    radius: Kirigami.Units.cornerRadius
                    color: shutdownArea.containsPress
                        ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.2)
                        : shutdownArea.containsMouse
                            ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
                            : "transparent"
                    Kirigami.Icon {
                        anchors.centerIn: parent
                        width: Kirigami.Units.iconSizes.medium
                        height: width
                        source: "system-shutdown"
                        active: shutdownArea.containsMouse
                        isMask: true
                        color: Kirigami.Theme.textColor
                    }
                    PlasmaComponents.ToolTip {
                        text: i18n("Shut Down")
                        visible: shutdownArea.containsMouse
                    }
                    MouseArea {
                        id: shutdownArea
                        anchors.fill: parent
                        hoverEnabled: true
                        cursorShape: Qt.PointingHandCursor
                        onClicked: {
                            folio.HomeScreenState.closeAppDrawer()
                            powerSession.requestShutdown()
                        }
                    }
                }
            }

            // Separator above user avatar
            Rectangle {
                anchors.bottom: userSection.top
                anchors.bottomMargin: Kirigami.Units.smallSpacing
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.leftMargin: Kirigami.Units.smallSpacing
                anchors.rightMargin: Kirigami.Units.smallSpacing
                height: 1
                color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.15)
            }

            // User avatar anchored to bottom — tooltip shows name, click opens user settings
            Rectangle {
                id: userSection
                anchors.bottom: parent.bottom
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.margins: Kirigami.Units.smallSpacing
                height: width
                radius: Kirigami.Units.cornerRadius
                color: userArea.containsPress
                    ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.2)
                    : userArea.containsMouse
                        ? Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)
                        : "transparent"

                KirigamiAddonsComponents.Avatar {
                    anchors.centerIn: parent
                    width: Kirigami.Units.iconSizes.medium
                    height: width
                    source: kuser.faceIconUrl
                    name: kuser.fullName || kuser.loginName
                }
                PlasmaComponents.ToolTip {
                    text: kuser.fullName || kuser.loginName
                    visible: userArea.containsMouse
                }
                MouseArea {
                    id: userArea
                    anchors.fill: parent
                    hoverEnabled: true
                    cursorShape: Qt.PointingHandCursor
                    onClicked: {
                        KCM.KCMLauncher.openSystemSettings("kcm_users")
                        folio.HomeScreenState.closeAppDrawer()
                    }
                }
            }
        }

        RunningAppsPanel {
            id: runningAppsPanel
            folio: root.folio

            x: categoryPanel.x + categoryPanel.width + overlayDrawer.connectedPanelGap
            y: overlayDrawer.y
            width: Math.max(0, parent.width - x - powerPanel.width - overlayDrawer.sideInset - overlayDrawer.connectedPanelGap)
            height: overlayDrawer.popupHeight
            opacity: overlayDrawer.opacity
            visible: hasTasks && opacity > 0

            onTaskActivated: folio.HomeScreenState.closeAppDrawer()
        }
    }

    // Game Center overlay — full-screen grid of games shown when gaming mode
    // is active.  Sits at LayerTop so it covers running application windows
    // without going above system notifications.
    GameCenterOverlay {
        id: gameCenterOverlay
        folio: root.folio
        visible: ShellSettings.Settings.gamingModeEnabled && root.gameCenterOpen

        onGameStarted: root.gameCenterOpen = false
        onDismissRequested: {
            root.gameCenterOpen = false
            if (ShellSettings.Settings.gamingDismissHintEnabled) {
                root.showGameCenterHint = true
                gameCenterHintTimer.restart()
            }
        }
    }

    // Small persistent button at the top-right corner of the screen that lets
    // the user return to the Game Center after launching a game.
    // Keep the Loader active for the full duration of gaming mode so the
    // opacity Behavior in GamingHUD can animate both fade-in and fade-out.
    //
    // Hide the HUD while a game window covers the screen. A mapped LayerShell
    // surface prevents KWin from using DRM direct scanout for the fullscreen
    // game window. Setting showing=false triggers the opacity fade-out and then
    // sets visible=false, which unmaps the Wayland surface and lets KWin bypass
    // the compositor render loop entirely for the game frame.
    Loader {
        active: ShellSettings.Settings.gamingModeEnabled
        sourceComponent: GamingHUD {
            visible: showing
            showing: !root.gameCenterOpen && !windowMaximizedTracker.showingWindow
            onOpenRequested: root.gameCenterOpen = true
        }
    }

    Rectangle {
        id: gameCenterHint
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.top: parent.top
        anchors.topMargin: Kirigami.Units.gridUnit * 2
        visible: root.showGameCenterHint && ShellSettings.Settings.gamingDismissHintEnabled
        opacity: visible ? 1 : 0
        z: 2000
        radius: Kirigami.Units.cornerRadius
        color: Qt.rgba(0, 0, 0, 0.65)
        border.width: 1
        border.color: Qt.rgba(1, 1, 1, 0.2)

        Behavior on opacity {
            MobileShell.MotionNumberAnimation { type: MobileShell.Motion.EffectsFast; duration: root.shortAnimationDuration }
        }

        implicitWidth: hintText.implicitWidth + Kirigami.Units.gridUnit * 2
        implicitHeight: hintText.implicitHeight + Kirigami.Units.largeSpacing

        PlasmaComponents.Label {
            id: hintText
            anchors.centerIn: parent
            text: i18n("Gaming mode is still on. Use Home or the gamepad icon to reopen Game Center.")
            color: "white"
            wrapMode: Text.WordWrap
            width: Math.min(root.width * 0.8, Kirigami.Units.gridUnit * 30)
            horizontalAlignment: Text.AlignHCenter
        }
    }

    MobileShell.HomeScreen {
        id: homeScreen
        anchors.fill: parent

        plasmoidItem: root
        onResetHomeScreenPosition: {
            // NOTE: empty, because this is handled by homeAction()
        }

        onHomeTriggered: root.homeAction()

        contentItem: Item {
            Item {
                id: workspaceFrame
                anchors.fill: parent
                visible: ShellSettings.Settings.convergenceModeEnabled
                         && !ShellSettings.Settings.gamingModeEnabled
                         && !folio.overviewActive
                z: -1

                readonly property real frameThickness: MobileShell.Constants.convergenceWorkspaceFrameThickness
                readonly property real frameRadius: Math.min(MobileShell.Constants.convergenceWorkspaceFrameRadius, Math.max(0, Math.min(workAreaWidth, workAreaHeight) / 2))
                readonly property real topReservedHeight: MobileShell.Constants.topPanelHeight
                readonly property real bottomReservedHeight: MobileShell.Constants.convergenceDockHeight
                readonly property real workAreaX: frameThickness
                readonly property real workAreaY: topReservedHeight + frameThickness
                readonly property real workAreaWidth: Math.max(0, width - frameThickness * 2)
                readonly property real workAreaHeight: Math.max(0, height - topReservedHeight - bottomReservedHeight - frameThickness * 2)
                readonly property color frameColor: Kirigami.Theme.backgroundColor
                readonly property color edgeColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.1)

                Kirigami.Theme.inherit: false
                Kirigami.Theme.colorSet: Kirigami.Theme.Window

                Shape {
                    anchors.fill: parent

                    ShapePath {
                        fillColor: workspaceFrame.frameColor
                        fillRule: ShapePath.OddEvenFill
                        strokeWidth: 0

                        startX: 0
                        startY: workspaceFrame.topReservedHeight
                        PathLine { x: workspaceFrame.width; y: workspaceFrame.topReservedHeight }
                        PathLine { x: workspaceFrame.width; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }
                        PathLine { x: 0; y: workspaceFrame.height - workspaceFrame.bottomReservedHeight }
                        PathLine { x: 0; y: workspaceFrame.topReservedHeight }

                        PathMove { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY }
                        PathLine { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth - workspaceFrame.frameRadius; y: workspaceFrame.workAreaY }
                        PathArc { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth; y: workspaceFrame.workAreaY + workspaceFrame.frameRadius; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
                        PathLine { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight - workspaceFrame.frameRadius }
                        PathArc { x: workspaceFrame.workAreaX + workspaceFrame.workAreaWidth - workspaceFrame.frameRadius; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
                        PathLine { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight }
                        PathArc { x: workspaceFrame.workAreaX; y: workspaceFrame.workAreaY + workspaceFrame.workAreaHeight - workspaceFrame.frameRadius; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
                        PathLine { x: workspaceFrame.workAreaX; y: workspaceFrame.workAreaY + workspaceFrame.frameRadius }
                        PathArc { x: workspaceFrame.workAreaX + workspaceFrame.frameRadius; y: workspaceFrame.workAreaY; radiusX: workspaceFrame.frameRadius; radiusY: workspaceFrame.frameRadius }
                    }
                }

                Rectangle {
                    x: workspaceFrame.workAreaX
                    y: workspaceFrame.workAreaY
                    width: workspaceFrame.workAreaWidth
                    height: workspaceFrame.workAreaHeight
                    radius: workspaceFrame.frameRadius
                    color: "transparent"
                    border.width: 1
                    border.color: workspaceFrame.edgeColor
                }
            }

            // homescreen component
            FolioHomeScreen {
                id: folioHomeScreen
                folio: root.folio
                maskManager: root.maskManager
                anchors.fill: parent

                topMargin: homeScreen.topMargin
                bottomMargin: homeScreen.bottomMargin
                leftMargin: homeScreen.leftMargin
                rightMargin: homeScreen.rightMargin

                // Ensure is the focused item at start
                Component.onCompleted: forceActiveFocus()

                onWallpaperSelectorTriggered: wallpaperSelectorLoader.active = true
            }
        }
    }

    // top blur layer for items on top of the base homescreen
    MobileShell.BlurEffect {
        id: homescreenBlur
        anchors.fill: parent
        active: folio.FolioSettings.wallpaperBlurEffect > 1 && ((delegateDragItem.visible && folio.HomeScreenState.dragState.dropDelegate.type === Folio.FolioDelegate.Folder) || wallpaperSelectorLoader.active)
        visible: active
        fullBlur: 0

        sourceLayer: homeScreenLayer
        maskSourceLayer: frontMaskManager.maskLayer

        // stacking both wallpaper and homescreen layers so we can blur them in one pass
        Item {
            id: homeScreenLayer
            anchors.fill: parent
            opacity: 0

            // wallpaper blur
            ShaderEffectSource {
                anchors.fill: parent

                textureSize: homescreenBlur.textureSize
                sourceItem: Plasmoid.wallpaperGraphicsObject
                hideSource: false
            }

            // homescreen blur
            ShaderEffectSource {
                anchors.fill: parent

                textureSize: homescreenBlur.textureSize
                sourceItem: homeScreen
                hideSource: false
            }
        }
    }

    // drag and drop component
    DelegateDragItem {
        id: delegateDragItem
        folio: root.folio
        maskManager: root.frontMaskManager
    }

    // drag and drop for widgets
    WidgetDragItem {
        id: widgetDragItem
        folio: root.folio
    }

    // loader for wallpaper selector
    Loader {
        id: wallpaperSelectorLoader
        anchors.fill: parent
        asynchronous: true
        active: false

        onLoaded: {
            wallpaperSelectorLoader.item.open();
        }

        sourceComponent: MobileShell.WallpaperSelector {
            maskManager: root.frontMaskManager
            horizontal: root.width > root.height
            edge: horizontal ? Qt.LeftEdge : Qt.BottomEdge
            topMargin: horizontal ? folioHomeScreen.topMargin : 0
            bottomMargin: horizontal ? 0 : folioHomeScreen.bottomMargin
            leftMargin: horizontal ? folioHomeScreen.leftMargin : 0
            rightMargin: horizontal ? folioHomeScreen.rightMargin : 0
            onClosed: {
                wallpaperSelectorLoader.active = false;
            }

            onWallpaperSettingsRequested: {
                close();
                folioHomeScreen.openConfigure();
            }
        }
    }
}

