type CacheEntry<T> = { data: T; fetchedAt: number }

const store = new Map<string, CacheEntry<unknown>>()

export const CACHE_KEYS = {
  serverStats: 'servers:stats',
  serverCategories: 'servers:categories',
} as const

export function invalidateCachedQuery(key: string) {
  store.delete(key)
}

export function clearCachedQueries() {
  store.clear()
}

/**
 * stale-while-revalidate: return cached data immediately when fresh; revalidate in background when stale.
 */
export async function cachedFetch<T>(
  key: string,
  fetcher: () => Promise<T>,
  ttlMs = 30_000,
): Promise<{ data: T; fromCache: boolean }> {
  const now = Date.now()
  const hit = store.get(key) as CacheEntry<T> | undefined

  if (hit && now - hit.fetchedAt < ttlMs) {
    return { data: hit.data, fromCache: true }
  }

  if (hit) {
    void fetcher()
      .then((data) => {
        store.set(key, { data, fetchedAt: Date.now() })
      })
      .catch(() => {})
    return { data: hit.data, fromCache: true }
  }

  const data = await fetcher()
  store.set(key, { data, fetchedAt: now })
  return { data, fromCache: false }
}
