import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
import { RedisService } from './redis.service';
import { ChainType } from '@/domain/value-objects';

/**
 * 地址缓存服务
 * 缓存需要监控的地址集合，用于快速判断是否需要处理某个交易
 */
@Injectable()
export class AddressCacheService implements OnModuleInit {
  private readonly logger = new Logger(AddressCacheService.name);
  private readonly CACHE_KEY_PREFIX = 'mining_blockchain:monitored_addresses:';

  constructor(private readonly redis: RedisService) {}

  async onModuleInit() {
    this.logger.log('AddressCacheService initialized');
  }

  private getCacheKey(chainType: ChainType): string {
    return `${this.CACHE_KEY_PREFIX}${chainType.toString().toLowerCase()}`;
  }

  /**
   * 检查地址是否在监控列表中
   */
  async isMonitored(chainType: ChainType, address: string): Promise<boolean> {
    const key = this.getCacheKey(chainType);
    return this.redis.sismember(key, address.toLowerCase());
  }

  /**
   * 添加地址到监控列表
   */
  async addAddress(chainType: ChainType, address: string): Promise<void> {
    const key = this.getCacheKey(chainType);
    await this.redis.sadd(key, address.toLowerCase());
    this.logger.debug(`Added address to cache: ${chainType} - ${address}`);
  }

  /**
   * 从监控列表移除地址
   */
  async removeAddress(chainType: ChainType, address: string): Promise<void> {
    const key = this.getCacheKey(chainType);
    await this.redis.srem(key, address.toLowerCase());
    this.logger.debug(`Removed address from cache: ${chainType} - ${address}`);
  }

  /**
   * 批量添加地址
   */
  async addAddresses(chainType: ChainType, addresses: string[]): Promise<void> {
    if (addresses.length === 0) return;
    const key = this.getCacheKey(chainType);
    const lowercased = addresses.map((a) => a.toLowerCase());
    await this.redis.sadd(key, ...lowercased);
    this.logger.debug(`Added ${addresses.length} addresses to cache: ${chainType}`);
  }

  /**
   * 获取所有监控地址
   */
  async getAllAddresses(chainType: ChainType): Promise<string[]> {
    const key = this.getCacheKey(chainType);
    return this.redis.smembers(key);
  }

  /**
   * 获取监控地址数量
   */
  async getCount(chainType: ChainType): Promise<number> {
    const key = this.getCacheKey(chainType);
    const client = this.redis.getClient();
    return client.scard(key);
  }

  /**
   * 重新加载缓存（从数据库）
   */
  async reloadCache(chainType: ChainType, addresses: string[]): Promise<void> {
    const key = this.getCacheKey(chainType);
    // 先删除旧缓存
    await this.redis.del(key);
    // 重新添加
    if (addresses.length > 0) {
      const lowercased = addresses.map((a) => a.toLowerCase());
      await this.redis.sadd(key, ...lowercased);
    }
    this.logger.log(`Reloaded cache for ${chainType}: ${addresses.length} addresses`);
  }
}
