// Request throttling utility to prevent too many API calls
class RequestThrottler {
  private requests: Map<string, number> = new Map();
  private readonly defaultDelay: number = 2000; // 2 seconds default delay

  constructor(defaultDelay: number = 2000) {
    this.defaultDelay = defaultDelay;
  }

  // Throttle a request by key
  async throttle<T>(
    key: string, 
    requestFn: () => Promise<T>, 
    delay: number = this.defaultDelay
  ): Promise<T> {
    const now = Date.now();
    const lastRequest = this.requests.get(key) || 0;
    
    if (now - lastRequest < delay) {
      // Wait for the remaining time
      const waitTime = delay - (now - lastRequest);
      await new Promise(resolve => setTimeout(resolve, waitTime));
    }
    
    this.requests.set(key, Date.now());
    return requestFn();
  }

  // Clear throttling for a specific key
  clear(key: string) {
    this.requests.delete(key);
  }

  // Clear all throttling
  clearAll() {
    this.requests.clear();
  }
}

// Global throttler instance
export const requestThrottler = new RequestThrottler(2000); // 2 second delay

// Debounce utility for search and filter operations
export function debounce<T extends (...args: any[]) => any>(
  func: T,
  delay: number
): (...args: Parameters<T>) => void {
  let timeoutId: NodeJS.Timeout;
  
  return (...args: Parameters<T>) => {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func(...args), delay);
  };
}

// Cache utility for API responses
class ApiCache {
  private cache: Map<string, { data: any; timestamp: number }> = new Map();
  private readonly defaultTTL: number = 10 * 60 * 1000; // 10 minutes

  constructor(defaultTTL: number = 10 * 60 * 1000) {
    this.defaultTTL = defaultTTL;
  }

  // Get cached data
  get<T>(key: string): T | null {
    const cached = this.cache.get(key);
    if (!cached) return null;
    
    const now = Date.now();
    if (now - cached.timestamp > this.defaultTTL) {
      this.cache.delete(key);
      return null;
    }
    
    return cached.data;
  }

  // Set cached data
  set<T>(key: string, data: T, ttl?: number): void {
    this.cache.set(key, {
      data,
      timestamp: Date.now()
    });
  }

  // Clear cache
  clear(key?: string): void {
    if (key) {
      this.cache.delete(key);
    } else {
      this.cache.clear();
    }
  }

  // Check if cache is valid
  isValid(key: string): boolean {
    const cached = this.cache.get(key);
    if (!cached) return false;
    
    const now = Date.now();
    return now - cached.timestamp <= this.defaultTTL;
  }
}

// Global cache instance
export const apiCache = new ApiCache(10 * 60 * 1000); // 10 minutes TTL

export default requestThrottler;
