/**
 * Redis Configuration
 *
 * Redis client for rate limiting, token blacklist, and caching
 */

import Redis from 'ioredis';
import { logger } from '../utils/logger';

/**
 * Redis client instance
 */
let redisClient: Redis | null = null;

/**
 * Initialize Redis connection
 */
export function initializeRedis(): Redis | null {
  // Support both REDIS_URL and REDIS_HOST/PORT formats
  const redisUrl = process.env.REDIS_URL ||
    (process.env.REDIS_HOST
      ? `redis://${process.env.REDIS_HOST}:${process.env.REDIS_PORT || '6379'}`
      : null);

  if (!redisUrl) {
    logger.warn('REDIS_URL not configured - rate limiting will use in-memory store');
    return null;
  }

  try {
    redisClient = new Redis(redisUrl, {
      maxRetriesPerRequest: 3,
      lazyConnect: false,
      enableReadyCheck: true,
      retryStrategy: (times: number) => {
        if (times > 3) return null; // stop retrying after 3 attempts
        return Math.min(times * 100, 3000);
      },
    });

    redisClient.on('connect', () => {
      logger.info('Redis connected successfully');
    });

    redisClient.on('error', (error) => {
      logger.error({ error }, 'Redis connection error');
    });

    redisClient.on('close', () => {
      logger.warn('Redis connection closed');
    });

    return redisClient;
  } catch (error) {
    logger.error({ error }, 'Failed to initialize Redis');
    return null;
  }
}

/**
 * Get Redis client instance
 */
export function getRedisClient(): Redis | null {
  return redisClient;
}

/**
 * Disconnect Redis client
 */
export async function disconnectRedis(): Promise<void> {
  if (redisClient) {
    await redisClient.quit();
    redisClient = null;
    logger.info('Redis disconnected');
  }
}

// Export singleton getter
export default { initializeRedis, getRedisClient, disconnectRedis };