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

@Injectable()
export class NonceManagerService {
  private readonly logger = new Logger(NonceManagerService.name);
  private redis: Redis;

  constructor(private config: ConfigService) {
    this.redis = new Redis(this.config.get('REDIS_URL') || 'redis://localhost:6379/2');
  }

  /** 获取并递增 Relayer 链上 nonce（Redis 原子操作，防 nonce 冲突） */
  async next(relayerAddress: string): Promise<number> {
    const key = `relayer:nonce:${relayerAddress}`;
    const nonce = await this.redis.incr(key);
    return nonce - 1; // incr returns value after increment
  }

  /** 初始化 nonce（从链上同步） */
  async initialize(relayerAddress: string, chainNonce: number): Promise<void> {
    const key = `relayer:nonce:${relayerAddress}`;
    await this.redis.set(key, chainNonce);
    this.logger.log(`Nonce initialized for ${relayerAddress}: ${chainNonce}`);
  }

  /** 检查用户 meta-tx nonce 是否已使用（防重放） */
  async isNonceUsed(userAddress: string, nonce: number): Promise<boolean> {
    const key = `user:nonce:${userAddress}`;
    return (await this.redis.sismember(key, nonce.toString())) === 1;
  }

  /** 标记用户 nonce 已使用 */
  async markNonceUsed(userAddress: string, nonce: number): Promise<void> {
    const key = `user:nonce:${userAddress}`;
    await this.redis.sadd(key, nonce.toString());
  }

  /** 获取用户每分钟请求计数（用于熔断） */
  async getUserRateCount(userAddress: string): Promise<number> {
    const key = `rate:${userAddress}`;
    const count = await this.redis.get(key);
    return parseInt(count || '0', 10);
  }

  /** 递增用户请求计数 */
  async incrementUserRate(userAddress: string): Promise<number> {
    const key = `rate:${userAddress}`;
    const count = await this.redis.incr(key);
    if (count === 1) {
      await this.redis.expire(key, 60); // 60秒过期
    }
    return count;
  }
}
