/**
 * Database query caching with Redis
 * Implements query result caching with automatic invalidation
 *
 * Note: This module uses optional dynamic import for @the-order/cache
 * to avoid requiring it as a direct dependency. If cache is not available,
 * queries will execute directly without caching.
 */
import { query } from './client';
// Cache client instance (lazy-loaded via dynamic import)
let cacheClientPromise = null;
/**
 * Get cache client (lazy-loaded via dynamic import)
 * Returns null if cache module is not available
 */
async function getCacheClient() {
    if (cacheClientPromise === null) {
        cacheClientPromise = (async () => {
            try {
                // Use dynamic import with a string literal that TypeScript can't resolve at compile time
                // This is done by constructing the import path dynamically
                const cacheModulePath = '@the-order/cache';
                // eslint-disable-next-line @typescript-eslint/no-implied-eval
                const importFunc = new Function('specifier', 'return import(specifier)');
                const cacheModule = await importFunc(cacheModulePath);
                return cacheModule.getCacheClient();
            }
            catch {
                // Cache module not available - caching will be disabled
                return null;
            }
        })();
    }
    return cacheClientPromise;
}
/**
 * Execute a query with caching
 */
export async function cachedQuery(sql, params, options = {}) {
    const { ttl = 3600, keyPrefix = 'db:query:', enabled = true } = options;
    if (!enabled) {
        return query(sql, params);
    }
    const cache = await getCacheClient();
    if (!cache) {
        // Cache not available - execute query directly
        return query(sql, params);
    }
    const cacheKey = `${keyPrefix}${sql}:${JSON.stringify(params || [])}`;
    // Try to get from cache
    const cached = await cache.get(cacheKey);
    if (cached) {
        return cached;
    }
    // Execute query
    const result = await query(sql, params);
    // Cache result
    await cache.set(cacheKey, result, ttl);
    return result;
}
/**
 * Invalidate cache for a pattern
 */
export async function invalidateCache(pattern) {
    const cache = await getCacheClient();
    if (!cache) {
        return 0;
    }
    return cache.invalidate(`db:query:${pattern}*`);
}
/**
 * Invalidate cache for a specific query
 */
export async function invalidateQueryCache(sql, params) {
    const cache = await getCacheClient();
    if (!cache) {
        return;
    }
    const cacheKey = `db:query:${sql}:${JSON.stringify(params || [])}`;
    await cache.delete(cacheKey);
}
/**
 * Cache decorator for database functions
 * Note: This is a simplified implementation. In production, you'd need to
 * extract SQL and params from the function or pass them as metadata.
 */
export function cached(fn) {
    return (async (...args) => {
        const result = await fn(...args);
        return result;
    });
}
//# sourceMappingURL=query-cache.js.map