import { Redis } from "ioredis";
import { env } from "../../config/env.js";
import { logger } from "../observability/logger.js";

/**
 * msg 服务 Redis 客户端。
 *
 * 仲裁依据：
 * - REDIS_URL 可选，未配置时 redisClient=null，降级到 DB 唯一索引去重
 * - 用途：幂等去重（SETNX）、已读状态位图、未读计数缓存、频率限流
 *
 * 使用 lazy initialization：连接在首次调用 getRedis() 时建立。
 */
let redisInstance: Redis | null = null;
let connectAttempted = false;

export function getRedis(): Redis | null {
  if (!env.REDIS_URL) return null;
  if (!redisInstance && !connectAttempted) {
    connectAttempted = true;
    try {
      redisInstance = new Redis(env.REDIS_URL, {
        maxRetriesPerRequest: 3,
        enableReadyCheck: true,
        lazyConnect: false,
      });
      redisInstance.on("error", (err) => {
        logger.warn({ err }, "Redis client error");
      });
      redisInstance.on("connect", () => {
        logger.info("Redis connected");
      });
    } catch (err) {
      logger.warn({ err }, "Redis init failed, falling back to DB idempotency");
      redisInstance = null;
    }
  }
  return redisInstance;
}

export async function checkRedisConnection(): Promise<void> {
  const client = getRedis();
  if (!client) {
    logger.info("Redis disabled (REDIS_URL not set)");
    return;
  }
  try {
    const pong = await client.ping();
    if (pong === "PONG") {
      logger.info("Redis connection healthy");
    }
  } catch (err) {
    logger.warn({ err }, "Redis connection check failed");
  }
}

export async function closeRedis(): Promise<void> {
  if (redisInstance) {
    await redisInstance.quit();
    redisInstance = null;
    connectAttempted = false;
    logger.info("Redis disconnected");
  }
}
