// Lightweight TTL cache backed by localStorage so resolved Nostr data (author
// profiles, long-form events) survives page reloads and navigation instead of
// being re-queried from relays every visit. No-ops on the server and degrades
// silently on quota/parse errors so it can never break rendering.

const PREFIX = "bbe:nostr:";

interface Entry<T> {
  v: T;
  t: number; // stored-at epoch ms
}

export function readCache<T>(key: string, ttlMs: number): T | null {
  if (typeof window === "undefined") return null;
  try {
    const raw = window.localStorage.getItem(PREFIX + key);
    if (!raw) return null;
    const entry = JSON.parse(raw) as Entry<T>;
    if (Date.now() - entry.t > ttlMs) {
      window.localStorage.removeItem(PREFIX + key);
      return null;
    }
    return entry.v;
  } catch {
    return null;
  }
}

export function writeCache<T>(key: string, value: T): void {
  if (typeof window === "undefined") return;
  const payload = JSON.stringify({ v: value, t: Date.now() } satisfies Entry<T>);
  try {
    window.localStorage.setItem(PREFIX + key, payload);
  } catch {
    // Quota exceeded (or similar): evict our namespace and retry once.
    try {
      pruneNamespace();
      window.localStorage.setItem(PREFIX + key, payload);
    } catch {
      // Give up silently — caching is best-effort.
    }
  }
}

// Removes every entry written by this cache to recover space when localStorage
// is full. Only touches our own namespace.
function pruneNamespace(): void {
  for (let i = window.localStorage.length - 1; i >= 0; i--) {
    const k = window.localStorage.key(i);
    if (k && k.startsWith(PREFIX)) window.localStorage.removeItem(k);
  }
}
