// Gaming: what the machine is doing now, and what it should do while you play.
//
// Live first, because unlike every other page here this one has a genuinely
// live dimension -- "is Game Mode actually on, and how hot is the card" is the
// question that brings someone here mid-session.
//
// The part that makes this Panama's page rather than a gamemode config editor
// is "While a game is running": gamemode runs a script when a game starts and
// another when it exits, so the power profile and Do Not Disturb can follow the
// game and be put back afterwards -- back to what they were, not to a default.

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

SettingsPage {
    id: root

    objectName: "gaming"
    title: "Gaming"
    lede: "What this machine is doing, and how it should behave while you play."

    readonly property var gpu: Gaming.primaryGpu

    // Polling only while this page is on screen.
    Component.onCompleted: {
        Gaming.refresh();
        Gaming.watching = true;
    }
    Component.onDestruction: Gaming.watching = false

    TextRow {
        visible: Gaming.lastError !== ""
        label: "Gaming needs attention"
        detail: Gaming.lastError
        value: ""
        divider: false
    }

    // ── Right now ────────────────────────────────────────────────────────────

    SettingsCard {
        Column {
            width: parent.width
            spacing: 8

            Row {
                width: parent.width
                spacing: 12

                Text {
                    text: Gaming.active ? "Playing" : "Idle"
                    color: Theme.fg
                    font.family: Theme.fontFamily
                    font.pixelSize: Theme.fontSizeTitle
                    font.weight: Font.DemiBold
                }

                Text {
                    anchors.verticalCenter: parent.verticalCenter
                    text: Gaming.active
                        ? "Game Mode is engaged"
                        : "No game has requested Game Mode"
                    color: Theme.fgDim
                    font.family: Theme.fontFamily
                    font.pixelSize: Theme.fontSize
                }
            }
        }

        Repeater {
            model: Gaming.gpus

            delegate: TextRow {
                required property var modelData
                required property int index
                width: parent.width
                label: modelData.discrete ? "Graphics card" : "Integrated graphics"
                detail: String(modelData.driver ?? "")
                    + (modelData.discrete ? " · the one games use" : " · idle unless something asks for it")
                value: Gaming.gpuSummary(modelData)
                divider: true
            }
        }

        TextRow {
            label: "CPU governor"
            detail: "What the cores are scaling to right now"
            value: String(Gaming.gameMode?.governorNow ?? "unknown")
            divider: false
        }
    }

    // ── What Panama does about it ────────────────────────────────────────────

    SettingsCard {
        title: "While a game is running"
        subtitle: Gaming.gameMode?.hooksInstalled === true
            ? "Panama reacts when Game Mode engages, and puts everything back when the game exits."
            : "Panama can react when Game Mode engages. This needs a hook in gamemode's configuration."

        ActionRow {
            visible: Gaming.gameMode?.hooksInstalled !== true
            label: "Let Panama react to games"
            detail: "Adds a start and end hook to your gamemode configuration. Nothing else in that file is touched."
            action: "Enable"
            enabled: !Gaming.busy && Gaming.gameMode?.available === true
            onTriggered: Gaming.installHooks()
        }

        ToggleRow {
            visible: Gaming.gameMode?.hooksInstalled === true
            setting: "gamingPerformanceProfile"
        }

        // Silencing while a game runs is a focus mode with a trigger, and it
        // now lives with the others -- so "something silenced my notifications"
        // has one answer rather than two places to look.
        ActionRow {
            visible: Gaming.gameMode?.hooksInstalled === true
            label: "Silence notifications"
            detail: {
                const mode = FocusModes.modes.find(entry => entry.id === "gaming");
                if (!mode)
                    return "Handled by a focus mode on Notifications & Focus.";
                return mode.enabled === true
                    ? "Handled by the Gaming focus mode, which is on."
                    : "The Gaming focus mode is off, so notifications are not silenced.";
            }
            action: "Open Focus"
            onTriggered: ShellState.settingsPage = "notifications"
        }

        ToggleRow {
            visible: Gaming.gameMode?.hooksInstalled === true
            setting: "gamingNotifyOnStart"
        }

        ActionRow {
            visible: Gaming.gameMode?.hooksInstalled === true
            label: "Stop reacting to games"
            detail: "Removes the hooks. The settings above are kept."
            action: "Disable"
            enabled: !Gaming.busy
            divider: false
            onTriggered: Gaming.removeHooks()
        }
    }

    // ── Game Mode itself ─────────────────────────────────────────────────────

    SettingsCard {
        title: "Game Mode"
        subtitle: Gaming.gameMode?.available === true
            ? "Applied by gamemode to a game while it runs, then undone."
            : "gamemode is not installed."

        TextRow {
            label: "Daemon"
            detail: Gaming.gameMode?.daemonRunning === true
                ? "Running, waiting for a game to ask"
                : "Not running, so no game can request it"
            value: Gaming.gameMode?.daemonRunning === true ? "Running" : "Stopped"
        }

        // Said plainly rather than implied: on a machine already running the
        // governor gamemode would switch to, its headline effect is nothing.
        TextRow {
            label: "Governor while gaming"
            detail: Gaming.governorAlreadyThere
                ? "This machine already runs that governor, so Game Mode changes nothing here"
                : "Switched for the duration of the game"
            value: String(Gaming.gameMode?.governorWhileGaming ?? "unknown")
            divider: false
        }
    }

    // ── Overlay ──────────────────────────────────────────────────────────────

    SettingsCard {
        title: "Performance overlay"
        subtitle: Gaming.overlay?.installed === true
            ? "MangoHud, drawn on top of the game."
            : "MangoHud is not installed."

        SwitchRow {
            label: "Show the overlay in games"
            detail: "Takes effect for games launched after your next sign-in, because it is read from the session environment"
            checked: Gaming.overlay?.globallyEnabled === true
            enabled: !Gaming.busy && Gaming.overlay?.installed === true
            onToggled: value => Gaming.setOverlay(value)
        }

        SegmentRow {
            label: "What it shows"
            detail: "Frame rate alone, or the full readout with GPU and CPU"
            options: [
                { value: "fps", label: "Frame rate" },
                { value: "detailed", label: "Detailed" }
            ]
            value: String(Gaming.overlay?.preset ?? "fps")
            enabled: !Gaming.busy && Gaming.overlay?.installed === true
            onSelected: value => Gaming.setOverlayPreset(value)
        }

        TextRow {
            label: "Toggle in game"
            detail: "Shows and hides the overlay without leaving the game"
            value: String(Gaming.overlay?.toggleKey ?? "")
            divider: false
        }
    }

    // ── Library ──────────────────────────────────────────────────────────────

    SettingsCard {
        title: "Library"
        subtitle: "Where games live, and what can run them."

        TextRow {
            label: "Installed games"
            detail: String(Gaming.library?.path ?? "")
            value: String(Gaming.library?.games ?? 0)
        }

        // Listed, not chosen. Steam picks the runtime per game in its own
        // properties, and a control here would be claiming an authority this
        // page does not have.
        Repeater {
            model: Gaming.library?.protonBuilds ?? []

            delegate: TextRow {
                required property var modelData
                required property int index
                width: parent.width
                label: String(modelData.name ?? "")
                detail: modelData.community === true
                    ? "Community build · chosen per game in Steam"
                    : "Valve · chosen per game in Steam"
                value: "Installed"
                divider: true
            }
        }

        TextRow {
            label: "gamescope"
            detail: "Micro-compositor for scaling and frame limiting, used per game from Steam"
            value: Gaming.library?.gamescope === true ? "Available" : "Not installed"
            divider: false
        }
    }
}
