/**
 * API Cache and Request Deduplication Manager
 * Optimizes frontend-backend communication by:
 * - Caching API responses
 * - Deduplicating simultaneous requests
 * - Reducing unnecessary network traffic
 */

class APICache {
  constructor() {
    this.cache = new Map();
    this.pendingRequests = new Map();
    this.defaultTTL = 5 * 60 * 1000; // 5 minutes default

    // Custom TTL for different endpoints
    this.ttlConfig = {
      "/api/products": 5 * 60 * 1000, // 5 min
      "/api/products/featured": 10 * 60 * 1000, // 10 min
      "/api/categories": 30 * 60 * 1000, // 30 min
      "/api/portfolio/projects": 10 * 60 * 1000, // 10 min
      "/api/blog/posts": 5 * 60 * 1000, // 5 min
      "/api/pages": 10 * 60 * 1000, // 10 min
    };

    // Start periodic cleanup
    this.startCleanup();
  }

  /**
   * Get cache key from URL
   */
  getCacheKey(url) {
    return url;
  }

  /**
   * Get TTL for specific endpoint
   */
  getTTL(url) {
    // Match base endpoint
    for (const [endpoint, ttl] of Object.entries(this.ttlConfig)) {
      if (url.startsWith(endpoint)) {
        return ttl;
      }
    }
    return this.defaultTTL;
  }

  /**
   * Check if cache entry is valid
   */
  isValid(entry) {
    return entry && Date.now() - entry.timestamp < entry.ttl;
  }

  /**
   * Get from cache
   */
  get(url) {
    const key = this.getCacheKey(url);
    const entry = this.cache.get(key);

    if (this.isValid(entry)) {
      console.log(`[Cache] HIT: ${url}`);
      return entry.data;
    }

    console.log(`[Cache] MISS: ${url}`);
    return null;
  }

  /**
   * Set cache entry
   */
  set(url, data) {
    const key = this.getCacheKey(url);
    const ttl = this.getTTL(url);

    this.cache.set(key, {
      data,
      timestamp: Date.now(),
      ttl,
    });

    console.log(`[Cache] SET: ${url} (TTL: ${ttl}ms)`);
  }

  /**
   * Clear specific cache entry
   */
  clear(url) {
    const key = this.getCacheKey(url);
    this.cache.delete(key);
    console.log(`[Cache] CLEAR: ${url}`);
  }

  /**
   * Clear all cache
   */
  clearAll() {
    this.cache.clear();
    console.log("[Cache] CLEARED ALL");
  }

  /**
   * Fetch with caching and deduplication
   */
  async fetch(url, options = {}) {
    // Only cache GET requests
    if (options.method && options.method !== "GET") {
      return fetch(url, options);
    }

    // Check cache first
    const cached = this.get(url);
    if (cached) {
      return {
        json: async () => cached,
        ok: true,
        status: 200,
        fromCache: true,
      };
    }

    // Check if request is already pending
    if (this.pendingRequests.has(url)) {
      console.log(`[Cache] DEDUP: ${url} - Waiting for pending request`);
      return this.pendingRequests.get(url);
    }

    // Make new request
    console.log(`[Cache] FETCH: ${url}`);
    const requestPromise = fetch(url, options)
      .then(async (response) => {
        if (!response.ok) {
          throw new Error(`HTTP ${response.status}`);
        }

        const data = await response.json();

        // Cache successful response
        this.set(url, data);

        // Remove from pending
        this.pendingRequests.delete(url);

        return {
          json: async () => data,
          ok: true,
          status: response.status,
          fromCache: false,
        };
      })
      .catch((error) => {
        // Remove from pending on error
        this.pendingRequests.delete(url);
        throw error;
      });

    // Store as pending
    this.pendingRequests.set(url, requestPromise);

    return requestPromise;
  }

  /**
   * Periodic cleanup of expired entries
   */
  startCleanup() {
    setInterval(() => {
      let removed = 0;
      for (const [key, entry] of this.cache.entries()) {
        if (!this.isValid(entry)) {
          this.cache.delete(key);
          removed++;
        }
      }
      if (removed > 0) {
        console.log(`[Cache] Cleanup: Removed ${removed} expired entries`);
      }
    }, 60000); // Run every minute
  }

  /**
   * Get cache statistics
   */
  getStats() {
    return {
      size: this.cache.size,
      pending: this.pendingRequests.size,
      entries: Array.from(this.cache.entries()).map(([key, entry]) => ({
        url: key,
        age: Date.now() - entry.timestamp,
        ttl: entry.ttl,
        valid: this.isValid(entry),
      })),
    };
  }
}

// Create global instance
window.apiCache = new APICache();

// Expose cache clearing for manual control
window.clearAPICache = () => window.apiCache.clearAll();
