import { cache, HOUR_MS } from '$lib/server/cache';
import { fetchPublications } from './publications';

const CONSTELLATION = 'https://constellation.microcosm.blue';

/**
 * Counts the distinct identities (DIDs) that link to `target` via a given
 * `collection`/`path` in the Constellation backlink index. Used for engagement
 * signals like subscribers and recommends. Cached per-target for 1 hour; returns
 * 0 on any failure so callers can simply hide a zero-count chip.
 */
export async function countDistinctDids(
	target: string,
	collection: string,
	path: string
): Promise<number> {
	const cacheKey = `constellation:${collection}:${target}`;
	const cached = cache.get(cacheKey) as { count: number } | null;
	if (cached) {
		return cached.count;
	}

	try {
		const url =
			`${CONSTELLATION}/links/count/distinct-dids` +
			`?target=${encodeURIComponent(target)}` +
			`&collection=${encodeURIComponent(collection)}` +
			`&path=${encodeURIComponent(path)}`;
		const res = await fetch(url);
		if (!res.ok) {
			console.warn(`Constellation count failed: ${res.status} ${res.statusText}`);
			return 0;
		}
		const { total } = (await res.json()) as { total?: number };
		const count = total ?? 0;
		cache.setWithExpiry(cacheKey, { count }, HOUR_MS);
		return count;
	} catch (error) {
		console.warn('Failed to fetch Constellation count:', error);
		return 0;
	}
}

/**
 * Maps each surfaced publication's at-uri to its subscriber count
 * (`site.standard.graph.subscription` records pointing at the publication).
 */
export async function fetchSubscriberCounts(): Promise<Record<string, number>> {
	const publications = await fetchPublications();
	const counts = await Promise.all(
		publications.map((pub) =>
			countDistinctDids(pub.uri, 'site.standard.graph.subscription', '.publication')
		)
	);

	const byUri: Record<string, number> = {};
	publications.forEach((pub, i) => {
		byUri[pub.uri] = counts[i];
	});
	return byUri;
}
