pragma Singleton
pragma ComponentBehavior: Bound

import "root:/modules/common"
import "root:/modules/common/functions/object_utils.js" as ObjectUtils
import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import Qt.labs.platform

Singleton {
    id: root
    property string fileDir: XdgDirectories.state
    property string fileName: "states.json"
    property string filePath: `${root.fileDir}/${root.fileName}`
    property bool allowWriteback: false

    function getState(nestedKey) {
        let keys = nestedKey.split(".");
        let obj = PersistentStates;
        for (let i = 0; i < keys.length; ++i) {
            if (obj[keys[i]] === undefined) {
                console.error(`[PersistentStateManager] Key "${keys[i]}" not found in PersistentStates`);
                return null;
            }
            obj = obj[keys[i]];
        }
        return obj;
    }

    function setState(nestedKey, value) {
        if (!root.allowWriteback) return;
        let keys = nestedKey.split(".");
        let obj = PersistentStates;
        let parents = [obj];

        // Traverse and collect parent objects
        for (let i = 0; i < keys.length - 1; ++i) {
            if (!obj[keys[i]] || typeof obj[keys[i]] !== "object") {
                obj[keys[i]] = {};
            }
            obj = obj[keys[i]];
            parents.push(obj);
        }

        // Set the value at the innermost key
        obj[keys[keys.length - 1]] = value;

        saveStates()
    }

    function loadStates() {
        stateFileView.reload()
    }

    function saveStates() {
        const plainStates = ObjectUtils.toPlainObject(PersistentStates)
        stateFileView.setText(JSON.stringify(plainStates, null, 2))
    }

    function applyStates(fileContent) {
        try {
            const json = JSON.parse(fileContent);
            ObjectUtils.applyToQtObject(PersistentStates, json);
            root.allowWriteback = true
        } catch (e) {
            console.error("[PersistentStateManager] Error reading file:", e);
            return;
        }
    }

    Timer {
        id: delayedFileRead
        interval: ConfigOptions.hacks.arbitraryRaceConditionDelay
        repeat: false
        running: false
        onTriggered: {
            root.applyStates(stateFileView.text())
        }
    }

	FileView { 
        id: stateFileView
        path: root.filePath
        watchChanges: true
        // onFileChanged: {
        //     console.log("[PersistentStateManager] File changed, reloading...")
        //     this.reload()
        //     delayedFileRead.start()
        // }
        onLoadedChanged: {
            const fileContent = stateFileView.text()
            root.applyStates(fileContent)
        }
        onLoadFailed: (error) => {
            console.log("[PersistentStateManager] File not found, creating new file")
            root.saveStates()
        }
    }
}
