import { Injectable, OnModuleDestroy } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import Redis from 'ioredis';

@Injectable()
export class RedisService implements OnModuleDestroy {
  private readonly client: Redis;

  constructor(private readonly configService: ConfigService) {
    this.client = new Redis({
      host: this.configService.get<string>('REDIS_HOST', 'localhost'),
      port: this.configService.get<number>('REDIS_PORT', 6379),
      password: this.configService.get<string>('REDIS_PASSWORD'),
      db: this.configService.get<number>('REDIS_DB', 0),
    });
  }

  async onModuleDestroy(): Promise<void> {
    await this.client.quit();
  }

  // ZSET 操作
  async zadd(key: string, score: number, member: string): Promise<number> {
    return this.client.zadd(key, score, member);
  }

  async zcount(key: string, min: number | string, max: number | string): Promise<number> {
    return this.client.zcount(key, min, max);
  }

  async zrangebyscore(
    key: string,
    min: number | string,
    max: number | string,
    withScores?: 'WITHSCORES',
    limit?: 'LIMIT',
    offset?: number,
    count?: number,
  ): Promise<string[]> {
    if (withScores && limit && offset !== undefined && count !== undefined) {
      return this.client.zrangebyscore(key, min, max, withScores, limit, offset, count);
    }
    if (limit && offset !== undefined && count !== undefined) {
      return this.client.zrangebyscore(key, min, max, limit, offset, count);
    }
    return this.client.zrangebyscore(key, min, max);
  }

  async zremrangebyscore(key: string, min: number | string, max: number | string): Promise<number> {
    return this.client.zremrangebyscore(key, min, max);
  }

  async zscore(key: string, member: string): Promise<string | null> {
    return this.client.zscore(key, member);
  }

  // HyperLogLog 操作
  async pfadd(key: string, ...elements: string[]): Promise<number> {
    return this.client.pfadd(key, ...elements);
  }

  async pfcount(...keys: string[]): Promise<number> {
    return this.client.pfcount(...keys);
  }

  // 通用操作
  async expire(key: string, seconds: number): Promise<number> {
    return this.client.expire(key, seconds);
  }

  async del(...keys: string[]): Promise<number> {
    return this.client.del(...keys);
  }
}
