/**
 * Small store that exposes counts for sidebar nav badges.
 *
 * Values reflect the last successful poll. Individual sources fail
 * independently — a failure keeps the previous value and flips `stale` true
 * so the UI can dim the badge if desired. The poller is intentionally
 * forgiving: if the user is unauthenticated or the backend isn't ready,
 * it silently retries on the next tick.
 *
 * Workload-first: legacy project / site / stack counts were retired with
 * the hard cutover. `workloads` is now the single "things you have"
 * counter, supplementing `apps` (the grouping primitive) and
 * `containers` (the running instances).
 */

import { writable, type Readable } from 'svelte/store';
import * as api from '$lib/api';
import { isAuthenticated } from '$lib/auth';

export interface NavCounts {
	apps: number | null;
	workloads: number | null;
	proxies: number | null;
	containers: number | null;
	/** Error-severity events only; dashboard surfaces total separately. */
	eventsErrors: number | null;
}

const EMPTY: NavCounts = {
	apps: null,
	workloads: null,
	proxies: null,
	containers: null,
	eventsErrors: null
};

const store = writable<NavCounts>(EMPTY);

export const navCounts: Readable<NavCounts> = { subscribe: store.subscribe };

let pollTimer: ReturnType<typeof setInterval> | null = null;
let inFlight: AbortController | null = null;

async function refreshOnce(): Promise<void> {
	if (inFlight || !isAuthenticated()) return;
	const ac = new AbortController();
	inFlight = ac;
	try {
		const [apps, workloads, proxies, containers, eventStats] = await Promise.allSettled([
			api.listApps(ac.signal),
			api.listWorkloads(undefined, ac.signal),
			api.listProxyRoutes(ac.signal),
			api.listContainers({}, ac.signal),
			api.fetchEventLogStats(ac.signal)
		]);

		if (ac.signal.aborted) return;
		store.update((prev) => ({
			apps: apps.status === 'fulfilled' ? apps.value.length : prev.apps,
			workloads: workloads.status === 'fulfilled' ? workloads.value.length : prev.workloads,
			proxies: proxies.status === 'fulfilled' ? proxies.value.length : prev.proxies,
			containers: containers.status === 'fulfilled' ? containers.value.length : prev.containers,
			eventsErrors: eventStats.status === 'fulfilled' ? eventStats.value.error : prev.eventsErrors
		}));
	} finally {
		if (inFlight === ac) inFlight = null;
	}
}

/**
 * Start periodic polling of nav counts. Safe to call repeatedly —
 * subsequent calls are no-ops until `stopNavCountsPolling()` is called.
 */
export function startNavCountsPolling(intervalMs = 60_000): void {
	if (pollTimer) return;
	void refreshOnce();
	pollTimer = setInterval(() => void refreshOnce(), intervalMs);
}

export function stopNavCountsPolling(): void {
	if (pollTimer) {
		clearInterval(pollTimer);
		pollTimer = null;
	}
	if (inFlight) {
		inFlight.abort();
		inFlight = null;
	}
}

/** Trigger an out-of-band refresh (e.g. after a mutation). */
export function refreshNavCounts(): void {
	void refreshOnce();
}
