pragma Singleton

import QtQuick
import Quickshell
import Quickshell.Wayland
import Quickshell.Io

Singleton {
    id: root

    // compositor stuff
    property string detectedCompositor: ""
    
    readonly property var backend: {
        if (detectedCompositor === "niri")
            return Niri
        if (detectedCompositor === "hyprland")
            return Hyprland
        return null
    }

    function require(compositors) { // This function can be effectively used to detect check requirements for a feature (also supports multiple compositors)
        if (Array.isArray(compositors)) {
            return compositors.includes(detectedCompositor);
        }
        return compositors === detectedCompositor;
    }

    // Unified api
    property string title: backend?.title ?? ""
    property bool isFullscreen: backend?.isFullscreen ?? false
    property string layout: backend?.layout ?? "Tiled"
    property int focusedWorkspaceId: backend?.focusedWorkspaceId ?? 1
    property var workspaces: backend?.workspaces ?? []
    property var windowList: backend?.windowList ?? []
    property bool initialized: backend?.initialized ?? true
    property int workspaceCount: backend?.workspaceCount ?? 0
    property real screenW: backend?.screenW ?? 0
    property real screenH: backend?.screenH ?? 0
    property real screenScale: backend?.screenScale ?? 1
    readonly property Toplevel activeToplevel: ToplevelManager.activeToplevel

    function changeWorkspace(id) {
        backend?.changeWorkspace?.(id)
    }

    function changeWorkspaceRelative(delta) {
        backend?.changeWorkspaceRelative?.(delta)
    }

    function isWorkspaceOccupied(id) {
        return backend?.isWorkspaceOccupied?.(id) ?? false
    }

    function focusedWindowForWorkspace(id) {
        return backend?.focusedWindowForWorkspace?.(id) ?? null
    }

    // process to detect compositor
    Process {
        command: ["sh", "-c", "echo \"$XDG_CURRENT_DESKTOP $XDG_SESSION_DESKTOP\""]
        running: true

        stdout: SplitParser {
            onRead: data => {
                if (!data)
                    return

                const val = data.trim().toLowerCase()

                if (val.includes("hyprland")) {
                    root.detectedCompositor = "hyprland"
                } else if (val.includes("niri")) {
                    root.detectedCompositor = "niri"
                }
            }
        }
    }

    signal stateChanged()

    Connections {
        target: backend
        function onStateChanged() {
            root.stateChanged()
        }
    }

}
