import { logger } from '@goodgo/logger';

// EN: Temporarily disable Redis to prevent EPIPE errors
// VI: Tạm thời tắt Redis để tránh lỗi EPIPE
// import { getRedisClient } from '../../config/redis.config';

/**
 * EN: Service for caching data (In-memory fallback, Redis disabled)
 * VI: Service cho việc caching dữ liệu (In-memory fallback, Redis đã tắt)
 */
export class CacheService {
    // EN: Temporary in-memory cache as fallback
    // VI: Cache in-memory tạm thời làm fallback
    private memoryCache: Map<string, { value: any; expiresAt: number }> = new Map();

    /**
     * EN: Get value from cache
     * VI: Lấy giá trị từ cache
     */
    async get<T>(key: string): Promise<T | null> {
        try {
            // EN: Use in-memory cache instead of Redis
            // VI: Sử dụng in-memory cache thay vì Redis
            const cached = this.memoryCache.get(key);
            if (!cached) return null;

            // Check expiration
            if (cached.expiresAt < Date.now()) {
                this.memoryCache.delete(key);
                return null;
            }

            return cached.value as T;

            // TODO: Re-enable after fixing Redis EPIPE errors
            // const data = await getRedisClient().get(key);
            // if (!data) return null;
            // return JSON.parse(data) as T;
        } catch (error) {
            logger.error('Cache get error', { key, error });
            return null;
        }
    }

    /**
     * EN: Set value in cache
     * VI: Lưu giá trị vào cache
     */
    async set(key: string, value: any, ttlSeconds: number = 300): Promise<void> {
        try {
            // EN: Use in-memory cache instead of Redis
            // VI: Sử dụng in-memory cache thay vì Redis
            const expiresAt = Date.now() + (ttlSeconds * 1000);
            this.memoryCache.set(key, { value, expiresAt });

            // TODO: Re-enable after fixing Redis EPIPE errors
            // const stringValue = JSON.stringify(value);
            // if (ttlSeconds) {
            //     await getRedisClient().setex(key, ttlSeconds, stringValue);
            // } else {
            //     await getRedisClient().set(key, stringValue);
            // }
        } catch (error) {
            logger.error('Cache set error', { key, error });
        }
    }

    /**
     * EN: Get from cache or fetch from source if missing
     * VI: Lấy từ cache hoặc lấy từ nguồn nếu không có
     */
    async getOrSet<T>(
        key: string,
        fetchFn: () => Promise<T>,
        ttlSeconds: number = 300
    ): Promise<T> {
        const cached = await this.get<T>(key);
        if (cached) return cached;

        const data = await fetchFn();
        await this.set(key, data, ttlSeconds);
        return data;
    }

    /**
     * EN: Delete from cache
     * VI: Xóa khỏi cache
     */
    async del(key: string): Promise<void> {
        try {
            // EN: Use in-memory cache instead of Redis
            // VI: Sử dụng in-memory cache thay vì Redis
            this.memoryCache.delete(key);

            // TODO: Re-enable after fixing Redis EPIPE errors
            // await getRedisClient().del(key);
        } catch (error) {
            logger.error('Cache del error', { key, error });
        }
    }
}

export const cacheService = new CacheService();
