/**
 * Offline message queue for Workshop panel.
 *
 * Persists undelivered job submissions to localStorage so they survive
 * page refreshes and are replayed when the server comes back online.
 */

const _QUEUE_KEY = "timmy_workshop_queue";
const _MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours — auto-expire old items

export const STATUS = {
    QUEUED: "queued",
    DELIVERED: "delivered",
    FAILED: "failed",
};

function _load() {
    try {
        const raw = localStorage.getItem(_QUEUE_KEY);
        return raw ? JSON.parse(raw) : [];
    } catch {
        return [];
    }
}

function _save(items) {
    try {
        localStorage.setItem(_QUEUE_KEY, JSON.stringify(items));
    } catch {
        /* localStorage unavailable — degrade silently */
    }
}

function _uid() {
    return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
}

/** LocalStorage-backed message queue for Workshop job submissions. */
export const messageQueue = {
    /** Add a payload. Returns the created item (with id and status). */
    enqueue(payload) {
        const item = {
            id: _uid(),
            payload,
            queuedAt: new Date().toISOString(),
            status: STATUS.QUEUED,
        };
        const items = _load();
        items.push(item);
        _save(items);
        return item;
    },

    /** Mark a message as delivered and remove it from storage. */
    markDelivered(id) {
        _save(_load().filter((i) => i.id !== id));
    },

    /** Mark a message as permanently failed (kept for 24h for visibility). */
    markFailed(id) {
        _save(
            _load().map((i) =>
                i.id === id ? { ...i, status: STATUS.FAILED } : i
            )
        );
    },

    /** All messages waiting to be delivered. */
    getPending() {
        return _load().filter((i) => i.status === STATUS.QUEUED);
    },

    /** Total queued (QUEUED status only) count. */
    pendingCount() {
        return this.getPending().length;
    },

    /** Drop expired failed items (> 24h old). */
    prune() {
        const cutoff = Date.now() - _MAX_AGE_MS;
        _save(
            _load().filter(
                (i) =>
                    i.status === STATUS.QUEUED ||
                    (i.status === STATUS.FAILED &&
                        new Date(i.queuedAt).getTime() > cutoff)
            )
        );
    },
};
