/**
 * Universal caching utility that works in both local and production environments
 *
 * - Local development: Uses node-cache (in-memory)
 * - Production (Vercel): Uses Vercel KV
 *
 * Environment-based cache selection:
 * 1. Explicit override: CACHE_TYPE=local or CACHE_TYPE=kv
 * 2. Auto-detect: KV_REST_API_URL or KV_URL present → Uses Vercel KV
 * 3. Fallback: Uses local node-cache
 *
 * Example usage:
 * ```typescript
 * import { CacheUtils } from '@/utils/cache';
 *
 * // Get from cache
 * const cached = await CacheUtils.get<MyType>('my-key', { logHit: true });
 *
 * // Set with TTL
 * await CacheUtils.set('my-key', data, 3600, { log: true }); // 1 hour TTL
 *
 * // Delete
 * await CacheUtils.del('my-key', { log: true });
 * ```
 */ import NodeCache from 'node-cache';
import { kv } from '@vercel/kv';
/**
 * Cache environment configuration
 */ const CACHE_CONFIG = {
    // Environment variables that indicate KV should be used
    KV_INDICATORS: [
        'KV_REST_API_URL',
        'KV_URL'
    ],
    // Allow explicit override via CACHE_TYPE env var
    CACHE_TYPE: process.env.CACHE_TYPE
};
/**
 * Determine cache type based on environment variables
 */ function getCacheType() {
    // Explicit override takes precedence
    if (CACHE_CONFIG.CACHE_TYPE === 'local') {
        return 'local';
    }
    if (CACHE_CONFIG.CACHE_TYPE === 'kv') {
        return 'kv';
    }
    // Auto-detect based on KV environment variables
    const hasKVConfig = CACHE_CONFIG.KV_INDICATORS.some((envVar)=>!!process.env[envVar]);
    return hasKVConfig ? 'kv' : 'local';
}
// Determine cache type at module load time
const cacheType = getCacheType();
// Initialize cache backends based on environment
let localCache = null;
if (cacheType === 'kv') {
    console.log('[Cache] Using Vercel KV cache');
} else {
    console.log('[Cache] Using local node-cache');
    localCache = new NodeCache({
        stdTTL: 60 * 60 * 24,
        checkperiod: 60 * 10,
        useClones: false
    });
}
/**
 * Universal cache utility functions
 */ export class CacheUtils {
    /**
   * Get a value from cache with optional logging
   */ static async get(key, options) {
        try {
            let value;
            if (cacheType === 'kv') {
                value = await kv.get(key);
            } else {
                value = localCache?.get(key);
            }
            // Fix: Only return null for missing keys (undefined), not for falsy values
            const result = value !== undefined ? value : null;
            if (options?.logHit) {
                if (result !== null) {
                    console.log(`[Cache] HIT: ${key}`);
                } else {
                    console.log(`[Cache] MISS: ${key}`);
                }
            }
            return result;
        } catch (error) {
            console.warn(`[Cache] Get error for key "${key}":`, error);
            return null;
        }
    }
    /**
   * Set a value in cache with TTL and logging
   */ static async set(key, value, ttlSeconds, options) {
        try {
            if (cacheType === 'kv') {
                if (ttlSeconds) {
                    await kv.set(key, value, {
                        ex: ttlSeconds
                    });
                } else {
                    await kv.set(key, value);
                }
            } else {
                const ttl = ttlSeconds || 60 * 60 * 24; // Default to 24 hours
                localCache?.set(key, value, ttl);
            }
            if (options?.log) {
                const ttlInfo = ttlSeconds ? ` (TTL: ${ttlSeconds}s)` : '';
                console.log(`[Cache] SET: ${key}${ttlInfo}`);
            }
        } catch (error) {
            console.warn(`[Cache] Set error for key "${key}":`, error);
        }
    }
    /**
   * Delete a key from cache
   */ static async del(key, options) {
        try {
            if (cacheType === 'kv') {
                await kv.del(key);
            } else {
                localCache?.del(key);
            }
            if (options?.log) {
                console.log(`[Cache] DEL: ${key}`);
            }
        } catch (error) {
            console.warn(`[Cache] Delete error for key "${key}":`, error);
        }
    }
    /**
   * Clear all cache entries (use with caution!)
   */ static async clear() {
        try {
            if (cacheType === 'kv') {
                await kv.flushdb();
            } else {
                localCache?.flushAll();
            }
            console.log('[Cache] Cleared all entries');
        } catch (error) {
            console.warn('[Cache] Clear error:', error);
        }
    }
    /**
   * Get current cache type for debugging/monitoring
   */ static getCacheType() {
        return cacheType;
    }
}
// Legacy exports for backward compatibility
export const cache = CacheUtils;
export { cacheType };
export default CacheUtils;
