import { CacheEntry, CacheInterface, CacheOptions } from '../types';

const DEFAULT_TTL = 5 * 60 * 1000; // 5 minutes in milliseconds

export class MemoryCache implements CacheInterface {
  private cache: Map<string, CacheEntry<unknown>>;
  private defaultTTL: number;

  constructor(defaultTTL = DEFAULT_TTL) {
    this.cache = new Map();
    this.defaultTTL = defaultTTL;
    
    // Periodically clean expired entries
    setInterval(() => this.cleanExpired(), 60 * 1000); // Clean every minute
  }

  get<T>(key: string): T | undefined {
    const entry = this.cache.get(key) as CacheEntry<T> | undefined;
    
    if (!entry) {
      return undefined;
    }
    
    // Check if the entry has expired
    if (entry.expires < Date.now()) {
      this.cache.delete(key);
      return undefined;
    }
    
    return entry.value;
  }

  set<T>(key: string, value: T, options?: Partial<CacheOptions>): void {
    const ttl = options?.ttl ?? this.defaultTTL;
    const expires = Date.now() + ttl;
    
    this.cache.set(key, { value, expires });
  }

  has(key: string): boolean {
    const entry = this.cache.get(key);
    
    if (!entry) {
      return false;
    }
    
    // Check if the entry has expired
    if (entry.expires < Date.now()) {
      this.cache.delete(key);
      return false;
    }
    
    return true;
  }

  delete(key: string): boolean {
    return this.cache.delete(key);
  }

  clear(): void {
    this.cache.clear();
  }

  private cleanExpired(): void {
    const now = Date.now();
    
    for (const [key, entry] of this.cache.entries()) {
      if (entry.expires < now) {
        this.cache.delete(key);
      }
    }
  }
}