pragma Singleton

// Carrying settings to another machine.
//
// Distinct from SettingsBackup, which snapshots this machine so it can be put
// back exactly as it was. This produces something meant to travel: the
// preferences that describe taste rather than hardware.
//
// The helper exports by allow-list from the preference schema, so a key added
// later that happens to hold a token cannot leak into a file somebody emails to
// themselves, and validates everything again on arrival.

import Quickshell
import Quickshell.Io
import QtQuick

Singleton {
    id: root

    readonly property string helperPath: Quickshell.shellDir + "/scripts/panama-settings-sync"

    // Where an export lands by default. Somewhere a person will find it again.
    readonly property string defaultPath:
        (Quickshell.env("HOME") ?? "") + "/panama-settings.json"

    property string lastError: ""
    property string lastAction: ""
    property int carried: 0
    property int applied: 0
    property var left: []
    property var changes: []
    property var skipped: []
    property string exportedFrom: ""
    property bool previewed: false

    readonly property bool busy: worker.running

    function run(action: string, path: string): void {
        if (worker.running)
            return;
        root.lastError = "";
        root.lastAction = action;
        worker.command = [root.helperPath, action, path];
        worker.running = true;
    }

    function exportTo(path: string): void { root.run("export", path); }
    function preview(path: string): void { root.run("preview", path); }
    function importFrom(path: string): void { root.run("import", path); }

    function absorb(text: string): void {
        try {
            const parsed = JSON.parse(text);
            root.lastError = String(parsed.error ?? "");
            root.carried = Number(parsed.carried ?? 0);
            root.applied = Number(parsed.applied ?? 0);
            root.left = Array.isArray(parsed.left) ? parsed.left : [];
            root.changes = Array.isArray(parsed.changes) ? parsed.changes : [];
            root.skipped = Array.isArray(parsed.skipped) ? parsed.skipped : [];
            root.exportedFrom = String(parsed.exportedFrom ?? "");
            root.previewed = root.lastAction === "preview" && root.lastError === "";
        } catch (error) {
            root.lastError = "Could not read the result.";
            console.warn("SettingsSync: could not parse helper output:", error);
        }
    }

    Process {
        id: worker
        stdout: StdioCollector { onStreamFinished: root.absorb(this.text) }
        stderr: StdioCollector {
            onStreamFinished: if (this.text.trim() !== "") root.lastError = this.text.trim()
        }
    }
}
