interface CacheEntry<T> {
  data: T;
  expiresAt: number;
}

class MailCache {
  private cache = new Map<string, CacheEntry<any>>();
  private readonly maxEntries = 1000;

  constructor() {
    setInterval(() => this.sweep(), 60_000);
  }

  get<T>(key: string): T | null {
    const entry = this.cache.get(key);
    if (!entry) return null;
    if (Date.now() > entry.expiresAt) {
      this.cache.delete(key);
      return null;
    }
    return entry.data as T;
  }

  set<T>(key: string, data: T, ttlMs: number) {
    if (this.cache.size >= this.maxEntries) this.sweep();
    this.cache.set(key, { data, expiresAt: Date.now() + ttlMs });
  }

  invalidateByPrefix(prefix: string) {
    for (const key of this.cache.keys()) {
      if (key.startsWith(prefix)) this.cache.delete(key);
    }
  }

  private sweep() {
    const now = Date.now();
    for (const [key, entry] of this.cache.entries()) {
      if (now > entry.expiresAt) this.cache.delete(key);
    }
  }
}

export const mailCache = new MailCache();
