pragma Singleton

// GNOME and GTK applications already honour these desktop sound preferences.
// Panama controls the same durable keys so moving between sessions does not
// create two competing notions of whether event feedback is enabled.

import Quickshell
import Quickshell.Io
import QtQuick

Singleton {
    id: root

    property bool eventSounds: true
    property bool inputFeedback: false
    property string lastError: ""
    readonly property bool busy: eventRead.running || inputRead.running
        || eventWrite.running || inputWrite.running

    function parsedBoolean(text: string, fallback: bool): bool {
        const value = text.trim();
        if (value === "true")
            return true;
        if (value === "false")
            return false;
        return fallback;
    }

    function refresh(): void {
        if (!eventRead.running)
            eventRead.running = true;
        if (!inputRead.running)
            inputRead.running = true;
    }

    function setEventSounds(enabled: bool): void {
        root.eventSounds = enabled;
        eventWrite.command = ["gsettings", "set", "org.gnome.desktop.sound", "event-sounds", String(enabled)];
        eventWrite.running = true;
    }

    function setInputFeedback(enabled: bool): void {
        root.inputFeedback = enabled;
        inputWrite.command = ["gsettings", "set", "org.gnome.desktop.sound", "input-feedback-sounds", String(enabled)];
        inputWrite.running = true;
    }

    Process {
        id: eventRead
        command: ["gsettings", "get", "org.gnome.desktop.sound", "event-sounds"]
        stdout: StdioCollector {
            onStreamFinished: root.eventSounds = root.parsedBoolean(this.text, root.eventSounds)
        }
        onExited: (code, status) => {
            if (code !== 0)
                root.lastError = "Event sound preferences could not be read.";
        }
    }

    Process {
        id: inputRead
        command: ["gsettings", "get", "org.gnome.desktop.sound", "input-feedback-sounds"]
        stdout: StdioCollector {
            onStreamFinished: root.inputFeedback = root.parsedBoolean(this.text, root.inputFeedback)
        }
        onExited: (code, status) => {
            if (code !== 0)
                root.lastError = "Input feedback preferences could not be read.";
        }
    }

    Process {
        id: eventWrite
        onExited: (code, status) => {
            if (code !== 0) {
                root.lastError = "Event sound preferences could not be changed.";
                root.refresh();
            } else {
                root.lastError = "";
            }
        }
    }

    Process {
        id: inputWrite
        onExited: (code, status) => {
            if (code !== 0) {
                root.lastError = "Input feedback preferences could not be changed.";
                root.refresh();
            } else {
                root.lastError = "";
            }
        }
    }

    Component.onCompleted: root.refresh()
}
