/**
 * Redis 클라이언트 (로그인 시도 제한, 토큰 블랙리스트)
 *
 * Redis 미연결 시 메모리 폴백으로 동작
 */

const { createClient } = require('redis');

const REDIS_HOST = process.env.REDIS_HOST || 'redis';
const REDIS_PORT = process.env.REDIS_PORT || 6379;

let client = null;
let connected = false;

// 메모리 폴백 (Redis 미연결 시)
const memoryStore = new Map();

async function initRedis() {
  try {
    client = createClient({ url: `redis://${REDIS_HOST}:${REDIS_PORT}` });
    client.on('error', () => { connected = false; });
    client.on('connect', () => { connected = true; });
    await client.connect();
    console.log('Redis 연결 성공');
  } catch {
    console.warn('Redis 연결 실패 - 메모리 폴백 사용');
    connected = false;
  }
}

async function get(key) {
  if (connected) {
    return await client.get(key);
  }
  const entry = memoryStore.get(key);
  if (!entry) return null;
  if (entry.expiry && entry.expiry < Date.now()) {
    memoryStore.delete(key);
    return null;
  }
  return entry.value;
}

async function set(key, value, ttlSeconds) {
  if (connected) {
    await client.set(key, value, { EX: ttlSeconds });
  } else {
    memoryStore.set(key, {
      value,
      expiry: ttlSeconds ? Date.now() + ttlSeconds * 1000 : null,
    });
  }
}

async function del(key) {
  if (connected) {
    await client.del(key);
  } else {
    memoryStore.delete(key);
  }
}

async function incr(key) {
  if (connected) {
    return await client.incr(key);
  }
  const entry = memoryStore.get(key);
  const current = entry ? parseInt(entry.value) || 0 : 0;
  const next = current + 1;
  memoryStore.set(key, { value: String(next), expiry: entry?.expiry || null });
  return next;
}

async function expire(key, ttlSeconds) {
  if (connected) {
    await client.expire(key, ttlSeconds);
  } else {
    const entry = memoryStore.get(key);
    if (entry) {
      entry.expiry = Date.now() + ttlSeconds * 1000;
    }
  }
}

module.exports = { initRedis, get, set, del, incr, expire };
