import Redis from 'ioredis';

let redisClient: Redis | null = null;

export function getRedisClient(): Redis | null {
  if (!process.env.REDIS_URL) {
    console.log('Redis URL not configured, caching disabled');
    return null;
  }

  if (!redisClient) {
    try {
      redisClient = new Redis(process.env.REDIS_URL, {
        maxRetriesPerRequest: 3,
        retryStrategy: (times) => {
          const delay = Math.min(times * 50, 2000);
          return delay;
        },
        reconnectOnError: (err) => {
          const targetError = 'READONLY';
          if (err.message.includes(targetError)) {
            // Only reconnect when the error contains "READONLY"
            return true;
          }
          return false;
        },
      });

      redisClient.on('error', (err) => {
        console.error('Redis Client Error:', err);
      });

      redisClient.on('connect', () => {
        console.log('Redis Client Connected');
      });
    } catch (error) {
      console.error('Failed to initialize Redis client:', error);
      return null;
    }
  }

  return redisClient;
}

export async function getCachedData<T>(key: string): Promise<T | null> {
  const client = getRedisClient();
  if (!client) return null;

  try {
    const data = await client.get(key);
    if (data) {
      return JSON.parse(data);
    }
  } catch (error) {
    console.error(`Error getting cached data for key ${key}:`, error);
  }
  return null;
}

export async function setCachedData<T>(
  key: string,
  data: T,
  ttlSeconds: number = 300 // Default 5 minutes
): Promise<void> {
  const client = getRedisClient();
  if (!client) return;

  try {
    await client.set(key, JSON.stringify(data), 'EX', ttlSeconds);
  } catch (error) {
    console.error(`Error setting cached data for key ${key}:`, error);
  }
}

export async function deleteCachedData(pattern: string): Promise<void> {
  const client = getRedisClient();
  if (!client) return;

  try {
    const keys = await client.keys(pattern);
    if (keys.length > 0) {
      await client.del(...keys);
    }
  } catch (error) {
    console.error(`Error deleting cached data for pattern ${pattern}:`, error);
  }
}

export async function flushCache(): Promise<void> {
  const client = getRedisClient();
  if (!client) return;

  try {
    await client.flushdb();
    console.log('Cache flushed successfully');
  } catch (error) {
    console.error('Error flushing cache:', error);
  }
}
