// Session-level avatar cache. Avatars are small (<100KB), referenced from
// many places (chat list, bubbles, dialogs), and rarely change — so keeping
// one blob-URL per remote URL avoids repeated decodes + network 304s across
// remounts. OPFS is optional; the in-memory map is enough for daily use.

const blobUrls = new Map<string, string>(); // remote URL → blob URL
const inflight = new Map<string, Promise<string | null>>();

async function fetchAsBlobUrl(url: string): Promise<string | null> {
  try {
    const res = await fetch(url, { cache: 'force-cache' });
    if (!res.ok) return null;
    const blob = await res.blob();
    return URL.createObjectURL(blob);
  } catch {
    return null;
  }
}

// Returns a cached blob URL for the avatar. Falls back to the original URL
// if caching fails so rendering never breaks.
export function useCachedAvatarUrl(url: string | null | undefined): string | null | undefined {
  if (!url) return url;
  return blobUrls.get(url) ?? url;
}

// Eagerly populate the cache for a list of URLs (e.g. conversation members)
// so subsequent renders hit the Map directly.
export function warmAvatarCache(urls: Array<string | null | undefined>): void {
  for (const url of urls) {
    if (!url) continue;
    if (blobUrls.has(url)) continue;
    if (inflight.has(url)) continue;
    const p = fetchAsBlobUrl(url).then((blobUrl) => {
      if (blobUrl) blobUrls.set(url, blobUrl);
      inflight.delete(url);
      return blobUrl;
    });
    inflight.set(url, p);
  }
}
