import { createClient, RedisClientType } from 'redis';

class RedisUtil {
  private client: RedisClientType | null = null;
  private static instance: RedisUtil;

  private constructor() {}

  public static getInstance(): RedisUtil {
    if (!RedisUtil.instance) {
      RedisUtil.instance = new RedisUtil();
    }
    return RedisUtil.instance;
  }

  async connect(): Promise<RedisClientType> {
    if (!this.client) {
      this.client = createClient({
        url: process.env.REDIS_URL || 'redis://127.0.0.1:6379'
      });

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

      await this.client.connect();
    }
    return this.client;
  }

  async disconnect(): Promise<void> {
    if (this.client) {
      await this.client.disconnect();
      this.client = null;
    }
  }

  async setSessionKey(userId: number, sessionKey: string, ttlSeconds: number = 7200): Promise<void> {
    const client = await this.connect();
    const key = `session_key:${userId}`;
    await client.set(key, sessionKey, {
      EX: ttlSeconds // 默认2小时过期，与微信session_key有效期一致
    });
  }

  async getSessionKey(userId: number): Promise<string | null> {
    const client = await this.connect();
    const key = `session_key:${userId}`;
    return await client.get(key);
  }

  async deleteSessionKey(userId: number): Promise<void> {
    const client = await this.connect();
    const key = `session_key:${userId}`;
    await client.del(key);
  }

  async isSessionKeyValid(userId: number): Promise<boolean> {
    const sessionKey = await this.getSessionKey(userId);
    return !!sessionKey;
  }

  /**
   * 设置系统配置缓存
   */
  async setSystemConfig(configKey: string, configValue: string, ttlSeconds: number = 3600): Promise<void> {
    const client = await this.connect();
    const key = `system_config:${configKey}`;
    await client.set(key, configValue, {
      EX: ttlSeconds // 默认1小时过期
    });
  }

  /**
   * 获取系统配置缓存
   */
  async getSystemConfig(configKey: string): Promise<string | null> {
    const client = await this.connect();
    const key = `system_config:${configKey}`;
    return await client.get(key);
  }

  /**
   * 删除系统配置缓存
   */
  async deleteSystemConfig(configKey: string): Promise<void> {
    const client = await this.connect();
    const key = `system_config:${configKey}`;
    await client.del(key);
  }

  /**
   * 批量获取系统配置缓存
   */
  async getSystemConfigs(configKeys: string[]): Promise<Record<string, string | null>> {
    const client = await this.connect();
    const keys = configKeys.map(key => `system_config:${key}`);
    const values = await client.mGet(keys);

    const result: Record<string, string | null> = {};
    configKeys.forEach((key, index) => {
      result[key] = values[index] ?? null;
    });

    return result;
  }

  /**
   * 设置空值缓存（防止缓存穿透）
   */
  async setNullSystemConfig(configKey: string, ttlSeconds: number = 300): Promise<void> {
    const client = await this.connect();
    const key = `system_config:${configKey}`;
    await client.set(key, '__NULL__', {
      EX: ttlSeconds // 默认5分钟过期
    });
  }

  /**
   * 检查是否为空值缓存
   */
  isNullValue(value: string | null): boolean {
    return value === '__NULL__';
  }

  /**
   * 格式化系统配置缓存键
   */
  formatSystemConfigKey(configKey: string): string {
    return `system_config:${configKey}`;
  }
}

export const redisUtil = RedisUtil.getInstance();