'use strict';
/**
 * Simple In-Memory Cache Service
 * Provides caching for frequently accessed, rarely changing data like settings
 * Does NOT change any API response format - purely internal optimization
 */

class CacheService {
    constructor() {
        this.cache = new Map();
        this.defaultTTL = 300; // 5 minutes default TTL in seconds
    }

    /**
     * Get item from cache
     * @param {string} key - Cache key
     * @returns {*} - Cached value or undefined if not found/expired
     */
    get(key) {
        const item = this.cache.get(key);
        if (!item) {
            return undefined;
        }

        // Check if expired
        if (Date.now() > item.expiresAt) {
            this.cache.delete(key);
            return undefined;
        }

        return item.value;
    }

    /**
     * Set item in cache
     * @param {string} key - Cache key
     * @param {*} value - Value to cache
     * @param {number} ttlSeconds - Time to live in seconds (default: 300)
     */
    set(key, value, ttlSeconds = this.defaultTTL) {
        this.cache.set(key, {
            value,
            expiresAt: Date.now() + (ttlSeconds * 1000)
        });
    }

    /**
     * Delete item from cache
     * @param {string} key - Cache key
     * @returns {boolean} - True if item was deleted
     */
    delete(key) {
        return this.cache.delete(key);
    }

    /**
     * Delete items matching a pattern (prefix)
     * @param {string} prefix - Key prefix to match
     * @returns {number} - Number of items deleted
     */
    deleteByPrefix(prefix) {
        let count = 0;
        for (const key of this.cache.keys()) {
            if (key.startsWith(prefix)) {
                this.cache.delete(key);
                count++;
            }
        }
        return count;
    }

    /**
     * Clear all cached items
     */
    clear() {
        this.cache.clear();
    }

    /**
     * Get or set pattern - fetch from cache or execute function and cache result
     * @param {string} key - Cache key
     * @param {Function} fetchFn - Async function to fetch data if not cached
     * @param {number} ttlSeconds - Time to live in seconds
     * @returns {*} - Cached or freshly fetched value
     */
    async getOrSet(key, fetchFn, ttlSeconds = this.defaultTTL) {
        let value = this.get(key);

        if (value !== undefined) {
            return value;
        }

        // Fetch fresh data
        value = await fetchFn();
        this.set(key, value, ttlSeconds);
        return value;
    }

    /**
     * Get cache statistics
     * @returns {Object} - Cache stats
     */
    getStats() {
        let validCount = 0;
        let expiredCount = 0;
        const now = Date.now();

        for (const item of this.cache.values()) {
            if (now > item.expiresAt) {
                expiredCount++;
            } else {
                validCount++;
            }
        }

        return {
            totalItems: this.cache.size,
            validItems: validCount,
            expiredItems: expiredCount
        };
    }
}

// Export singleton instance
module.exports = new CacheService();
