/**
 * Redis Configuration
 * Configures the Redis client using ioredis with robust connection handling
 * and retry strategies suitable for production environments.
 */

import Redis from 'ioredis';

const isRedisEnabled = process.env.ENABLE_REDIS_CACHE === 'true';

let redisClient = null;

if (isRedisEnabled) {
  const redisOptions = {
    // Connection Details
    host: process.env.REDIS_HOST || 'localhost',
    port: parseInt(process.env.REDIS_PORT || '6379', 10),
    password: process.env.REDIS_PASSWORD || undefined,
    db: parseInt(process.env.REDIS_DB || '0', 10),

    // Resilience Settings
    lazyConnect: true, // Don't crash application boot if Redis is unavailable
    connectTimeout: 10000, // 10 seconds
    commandTimeout: parseInt(process.env.REDIS_TIMEOUT || '100', 10), // Fail fast (default 100ms)

    // Retry Strategy: Capped Exponential Backoff
    retryStrategy: (times) => {
      const maxRetryTime = 3000; // 3 seconds cap
      // 50, 100, 200, 400, 800, 1600, 3000, 3000...
      const delay = Math.min(times * 50, maxRetryTime);

      console.warn(`[Redis] Connection lost. Retrying in ${delay}ms... (Attempt ${times})`);
      return delay;
    },

    // Reconnection handling
    reconnectOnError: (err) => {
      const targetError = 'READONLY';
      if (err.message.includes(targetError)) {
        // Only reconnect when the error starts with "READONLY"
        return true;
      }
      return false;
    }
  };

  // Support for Redis Connection URL if provided (overrides host/port)
  if (process.env.REDIS_URL) {
    redisClient = new Redis(process.env.REDIS_URL, redisOptions);
  } else {
    redisClient = new Redis(redisOptions);
  }

  // Event Logging
  redisClient.on('connect', () => {
    console.log('[Redis] Client connected successfully');
  });

  redisClient.on('error', (err) => {
    // Only log distinct connection errors to avoid flooding
    if (err.code === 'ECONNREFUSED') {
      console.error('[Redis] Connection refused - is the server running?');
    } else {
      console.error('[Redis] Error:', err.message);
    }
  });

  redisClient.on('ready', () => {
    console.log('[Redis] Client is ready to accept commands');
  });
} else {
  console.log('[Redis] Caching disabled via ENABLE_REDIS_CACHE environment variable');
}

export default redisClient;
