pragma Singleton

import Quickshell
import Quickshell.Io
import QtQuick

Singleton {
    id: root

    property string status: "loading"  // "loading" | "ok" | "degraded" | "error" | "stale"
    property var pods: []              // Array of {app, ready, cpuM, memMi}
    property int readyCount: 0
    property int totalCount: 0
    property var quota: null           // quota object from metrics script
    property int lastUpdatedSecs: 0    // seconds since last successful status fetch

    Process {
        id: statusProc
        command: ["bash", Config.scriptsDir + "/k8s-status.sh", Config.kubeNamespace]
        stdout: StdioCollector {
            onStreamFinished: {
                if (this.text.trim() === "") {
                    root.status = (root.status === "ok" || root.status === "degraded") ? "stale" : "error";
                    return;
                }
                try {
                    let data = JSON.parse(this.text);
                    // Preserve existing cpuM/memMi from last metrics fetch
                    let byApp = {};
                    for (let p of root.pods) byApp[p.app] = p;
                    root.pods = data.pods.map(p => ({
                        app:   p.app,
                        ready: p.ready,
                        cpuM:  byApp[p.app]?.cpuM  ?? -1,
                        memMi: byApp[p.app]?.memMi ?? -1
                    }));
                    root.readyCount = data.readyCount;
                    root.totalCount = data.totalCount;
                    root.status = data.pods.every(p => p.ready) ? "ok" : "degraded";
                    root.lastUpdatedSecs = 0;
                } catch(e) {
                    console.warn("Kubernetes: status parse error:", e);
                    root.status = (root.status === "ok" || root.status === "degraded") ? "stale" : "error";
                }
            }
        }
    }

    Process {
        id: metricsProc
        command: ["bash", Config.scriptsDir + "/k8s-metrics.sh", Config.kubeNamespace]
        stdout: StdioCollector {
            onStreamFinished: {
                if (this.text.trim() === "") return;
                try {
                    let data = JSON.parse(this.text);
                    let byApp = {};
                    for (let m of data.podMetrics) byApp[m.app] = m;
                    root.pods = root.pods.map(p => ({
                        app:   p.app,
                        ready: p.ready,
                        cpuM:  byApp[p.app]?.cpuM  ?? -1,
                        memMi: byApp[p.app]?.memMi ?? -1
                    }));
                    root.quota = data.quota;
                } catch(e) {
                    console.warn("Kubernetes: metrics parse error:", e);
                }
            }
        }
    }

    // Ticker: increments lastUpdatedSecs every second (only once status is known)
    Timer {
        interval: 1000
        running: root.status !== "loading"
        repeat: true
        onTriggered: root.lastUpdatedSecs++
    }

    // Force an immediate refresh (status always; metrics only while the popout is
    // open, where they're shown). Called on pill click and on popout open.
    function refresh() {
        statusProc.running = false; statusProc.running = true;
        if (PopoutState.active === "kubernetes") {
            metricsProc.running = false; metricsProc.running = true;
        }
    }

    readonly property bool popoutOpen: PopoutState.active === "kubernetes"
    onPopoutOpenChanged: if (popoutOpen) refresh()

    // Status poller — slow while the popout is closed (just the pill), fast while open.
    Timer {
        interval: root.popoutOpen ? Config.kubeRefreshOpenMs : Config.kubeStatusRefreshMs
        running: Config.kubeEnabled
        repeat: true
        onTriggered: statusProc.running = true
    }

    // Metrics poller — only while the popout is open, at the fast cadence.
    Timer {
        interval: Config.kubeRefreshOpenMs
        running: Config.kubeEnabled && root.popoutOpen
        repeat: true
        onTriggered: metricsProc.running = true
    }

    // Staleness check: flip to "stale" if no successful fetch for >60s
    Timer {
        interval: 10000
        running: true
        repeat: true
        onTriggered: {
            if (root.lastUpdatedSecs > 60 && (root.status === "ok" || root.status === "degraded"))
                root.status = "stale";
        }
    }

    Component.onCompleted: {
        if (Config.kubeEnabled)
            statusProc.running = true;
    }
}
