/**
 * API Key安全存储服务
 *
 * 功能描述：
 * - 实现Zulip API Key的加密存储
 * - 提供安全日志记录功能
 * - 检测异常操作并记录安全事件
 * - 支持API Key的安全获取和更新
 *
 * 职责分离：
 * - 加密存储层：负责API Key的安全加密和存储
 * - 安全监控层：检测和记录异常操作
 * - 访问控制层：控制API Key的访问权限
 *
 * 主要方法：
 * - storeApiKey(): 加密存储API Key
 * - getApiKey(): 安全获取API Key
 * - updateApiKey(): 更新API Key
 * - deleteApiKey(): 删除API Key
 * - logSecurityEvent(): 记录安全事件
 *
 * 使用场景：
 * - 用户首次绑定Zulip账户
 * - Zulip客户端创建时获取API Key
 * - 检测到异常操作时记录安全日志
 *
 * 依赖模块：
 * - AppLoggerService: 日志记录服务
 * - IRedisService: Redis缓存服务
 *
 * 最近修改：
 * - 2026-01-12: 代码规范优化 - 修正注释规范和修改记录格式 (修改者: moyin)
 * - 2026-01-07: 代码规范优化 - 更新import路径和注释规范 (修改者: moyin)
 *
 * @author moyin
 * @version 1.0.2
 * @since 2025-12-25
 * @lastModified 2026-01-12
 */

import { Injectable, Inject, Logger } from '@nestjs/common';
import * as crypto from 'crypto';
import { IRedisService } from '../../../core/redis/redis.interface';
import { IApiKeySecurityService } from '../zulip_core.interfaces';

/**
 * 安全事件类型枚举
 */
export enum SecurityEventType {
  API_KEY_STORED = 'api_key_stored',
  API_KEY_ACCESSED = 'api_key_accessed',
  API_KEY_UPDATED = 'api_key_updated',
  API_KEY_DELETED = 'api_key_deleted',
  API_KEY_DECRYPTION_FAILED = 'api_key_decryption_failed',
  SUSPICIOUS_ACCESS = 'suspicious_access',
  RATE_LIMIT_EXCEEDED = 'rate_limit_exceeded',
  INVALID_KEY_FORMAT = 'invalid_key_format',
  UNAUTHORIZED_ACCESS = 'unauthorized_access',
}

/**
 * 安全事件严重级别
 */
export enum SecuritySeverity {
  INFO = 'info',
  WARNING = 'warning',
  CRITICAL = 'critical',
}

/**
 * 安全事件记录接口
 */
export interface SecurityEvent {
  eventType: SecurityEventType;
  severity: SecuritySeverity;
  userId: string;
  details: Record<string, any>;
  timestamp: Date;
  ipAddress?: string;
  userAgent?: string;
}

/**
 * 加密后的API Key存储结构
 */
export interface EncryptedApiKey {
  encryptedKey: string;
  iv: string;
  authTag: string;
  createdAt: Date;
  updatedAt: Date;
  accessCount: number;
  lastAccessedAt?: Date;
}

/**
 * API Key存储结果
 */
export interface StoreApiKeyResult {
  success: boolean;
  message: string;
  userId?: string;
}

/**
 * API Key获取结果
 */
export interface GetApiKeyResult {
  success: boolean;
  apiKey?: string;
  message?: string;
}

/**
 * API密钥安全服务类
 *
 * 职责：
 * - 管理Zulip API密钥的安全存储
 * - 提供API密钥的加密和解密功能
 * - 记录API密钥的访问日志
 * - 监控API密钥的使用情况和安全事件
 *
 * 主要方法：
 * - storeApiKey(): 安全存储加密的API密钥
 * - retrieveApiKey(): 检索并解密API密钥
 * - validateApiKey(): 验证API密钥的有效性
 * - logSecurityEvent(): 记录安全相关事件
 * - getAccessStats(): 获取API密钥访问统计
 *
 * 使用场景：
 * - 用户API密钥的安全存储
 * - API密钥访问时的解密操作
 * - 安全事件的监控和记录
 * - API密钥使用情况的统计分析
 */
@Injectable()
export class ApiKeySecurityService implements IApiKeySecurityService {
  private readonly logger = new Logger(ApiKeySecurityService.name);
  private readonly API_KEY_PREFIX = 'zulip:api_key:';
  private readonly SECURITY_LOG_PREFIX = 'zulip:security_log:';
  private readonly ACCESS_COUNT_PREFIX = 'zulip:api_key_access:';
  private readonly ENCRYPTION_ALGORITHM = 'aes-256-gcm';
  private readonly KEY_LENGTH = 32; // 256 bits
  private readonly IV_LENGTH = 16; // 128 bits
  private readonly AUTH_TAG_LENGTH = 16; // 128 bits
  private readonly MAX_ACCESS_PER_MINUTE = 60; // 每分钟最大访问次数
  private readonly SECURITY_LOG_RETENTION = 30 * 24 * 3600; // 30天

  // 加密密钥（生产环境应从环境变量或密钥管理服务获取）
  private readonly encryptionKey: Buffer | null;

  constructor(
    @Inject('REDIS_SERVICE')
    private readonly redisService: IRedisService,
  ) {
    // 加密密钥必须由部署环境提供，不允许回退到共享的固定密钥。
    const keyFromEnv = process.env.ZULIP_API_KEY_ENCRYPTION_KEY;
    const degradedModeEnabled = process.env.ZULIP_DEGRADED_MODE_ENABLED === 'true';

    if (!keyFromEnv) {
      this.encryptionKey = null;

      if (!degradedModeEnabled) {
        throw new Error('ZULIP_API_KEY_ENCRYPTION_KEY未配置');
      }

      this.logger.warn(
        'Zulip降级模式已启用且未配置API Key加密密钥，API Key加密存取功能不可用',
      );
      return;
    }

    // 如果环境变量是十六进制格式，使用hex解析；否则使用utf8。
    if (/^[0-9a-fA-F]+$/.test(keyFromEnv) && keyFromEnv.length === 64) {
      this.encryptionKey = Buffer.from(keyFromEnv, 'hex');
    } else {
      const keyBuffer = Buffer.from(keyFromEnv, 'utf8');
      if (keyBuffer.length < this.KEY_LENGTH) {
        throw new Error('ZULIP_API_KEY_ENCRYPTION_KEY必须至少32字节');
      }
      this.encryptionKey = keyBuffer.subarray(0, this.KEY_LENGTH);
    }

    this.logger.log('ApiKeySecurityService初始化完成');
  }

  /**
   * 加密存储API Key
   *
   * 功能描述：
   * 使用AES-256-GCM算法加密API Key并存储到Redis
   *
   * 技术实现：
   * 1. 验证API Key格式
   * 2. 生成随机IV
   * 3. 使用AES-256-GCM加密
   * 4. 存储加密后的数据到Redis
   * 5. 记录安全日志
   *
   * @param userId 用户ID
   * @param apiKey Zulip API Key
   * @param metadata 可选的元数据（如IP地址）
   * @returns Promise<StoreApiKeyResult> 存储结果
   */
  async storeApiKey(
    userId: string,
    apiKey: string,
    metadata?: { ipAddress?: string; userAgent?: string }
  ): Promise<StoreApiKeyResult> {
    const startTime = Date.now();

    this.logger.log(`开始存储API Key: ${userId}`);

    try {
      // 1. 参数验证
      if (!userId || !userId.trim()) {
        await this.logSecurityEvent({
          eventType: SecurityEventType.INVALID_KEY_FORMAT,
          severity: SecuritySeverity.WARNING,
          userId: userId || 'unknown',
          details: { reason: 'empty_user_id' },
          timestamp: new Date(),
          ...metadata,
        });
        return { success: false, message: '用户ID不能为空' };
      }

      if (!apiKey || !apiKey.trim()) {
        await this.logSecurityEvent({
          eventType: SecurityEventType.INVALID_KEY_FORMAT,
          severity: SecuritySeverity.WARNING,
          userId,
          details: { reason: 'empty_api_key' },
          timestamp: new Date(),
          ...metadata,
        });
        return { success: false, message: 'API Key不能为空' };
      }

      // 2. 验证API Key格式（Zulip API Key通常是32字符的字母数字字符串）
      if (!this.isValidApiKeyFormat(apiKey)) {
        await this.logSecurityEvent({
          eventType: SecurityEventType.INVALID_KEY_FORMAT,
          severity: SecuritySeverity.WARNING,
          userId,
          details: { reason: 'invalid_format', keyLength: apiKey.length },
          timestamp: new Date(),
          ...metadata,
        });
        return { success: false, message: 'API Key格式无效' };
      }

      // 3. 加密API Key
      const encrypted = this.encrypt(apiKey);

      // 4. 构建存储数据
      const storageData: EncryptedApiKey = {
        encryptedKey: encrypted.encryptedData,
        iv: encrypted.iv,
        authTag: encrypted.authTag,
        createdAt: new Date(),
        updatedAt: new Date(),
        accessCount: 0,
      };

      // 5. 存储到Redis
      const storageKey = `${this.API_KEY_PREFIX}${userId}`;
      await this.redisService.set(storageKey, JSON.stringify(storageData));

      // 6. 记录安全日志
      await this.logSecurityEvent({
        eventType: SecurityEventType.API_KEY_STORED,
        severity: SecuritySeverity.INFO,
        userId,
        details: {
          action: 'store',
          keyLength: apiKey.length,
        },
        timestamp: new Date(),
        ...metadata,
      });

      const duration = Date.now() - startTime;
      this.logger.log(`API Key存储成功: ${userId}`);

      return { success: true, message: 'API Key存储成功', userId };

    } catch (error) {
      const err = error as Error;
      const duration = Date.now() - startTime;

      this.logger.error('API Key存储失败', {
        operation: 'storeApiKey',
        userId,
        error: err.message,
        duration,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return { success: false, message: '存储失败，请稍后重试' };
    }
  }


  /**
   * 安全获取API Key
   *
   * 功能描述：
   * 从Redis获取加密的API Key并解密返回
   *
   * 技术实现：
   * 1. 检查访问频率限制
   * 2. 从Redis获取加密数据
   * 3. 解密API Key
   * 4. 更新访问计数
   * 5. 记录访问日志
   *
   * @param userId 用户ID
   * @param metadata 可选的元数据
   * @returns Promise<GetApiKeyResult> 获取结果
   */
  async getApiKey(
    userId: string,
    metadata?: { ipAddress?: string; userAgent?: string }
  ): Promise<GetApiKeyResult> {
    const startTime = Date.now();

    this.logger.debug('开始获取API Key', {
      operation: 'getApiKey',
      userId,
      timestamp: new Date().toISOString(),
    });

    try {
      // 1. 参数验证
      if (!userId || !userId.trim()) {
        return { success: false, message: '用户ID不能为空' };
      }

      // 2. 检查访问频率限制
      const rateLimitCheck = await this.checkAccessRateLimit(userId);
      if (!rateLimitCheck.allowed) {
        await this.logSecurityEvent({
          eventType: SecurityEventType.RATE_LIMIT_EXCEEDED,
          severity: SecuritySeverity.WARNING,
          userId,
          details: {
            currentCount: rateLimitCheck.currentCount,
            limit: this.MAX_ACCESS_PER_MINUTE,
          },
          timestamp: new Date(),
          ...metadata,
        });
        return { success: false, message: '访问频率过高，请稍后重试' };
      }

      // 3. 从Redis获取加密数据
      const storageKey = `${this.API_KEY_PREFIX}${userId}`;
      const encryptedData = await this.redisService.get(storageKey);

      if (!encryptedData) {
        this.logger.debug('API Key不存在', {
          operation: 'getApiKey',
          userId,
        });
        return { success: false, message: 'API Key不存在' };
      }

      // 4. 解析存储数据
      const storageData: EncryptedApiKey = JSON.parse(encryptedData);

      // 5. 解密API Key
      let apiKey: string;
      try {
        apiKey = this.decrypt(
          storageData.encryptedKey,
          storageData.iv,
          storageData.authTag
        );
      } catch (decryptError) {
        await this.logSecurityEvent({
          eventType: SecurityEventType.API_KEY_DECRYPTION_FAILED,
          severity: SecuritySeverity.CRITICAL,
          userId,
          details: {
            error: (decryptError as Error).message,
          },
          timestamp: new Date(),
          ...metadata,
        });
        return { success: false, message: 'API Key解密失败' };
      }

      // 6. 更新访问计数和时间
      storageData.accessCount += 1;
      storageData.lastAccessedAt = new Date();
      await this.redisService.set(storageKey, JSON.stringify(storageData));

      // 7. 记录访问日志
      await this.logSecurityEvent({
        eventType: SecurityEventType.API_KEY_ACCESSED,
        severity: SecuritySeverity.INFO,
        userId,
        details: {
          accessCount: storageData.accessCount,
        },
        timestamp: new Date(),
        ...metadata,
      });

      const duration = Date.now() - startTime;
      this.logger.debug('API Key获取成功', {
        operation: 'getApiKey',
        userId,
        accessCount: storageData.accessCount,
        duration,
      });

      return { success: true, apiKey };

    } catch (error) {
      const err = error as Error;
      const duration = Date.now() - startTime;

      this.logger.error('API Key获取失败', {
        operation: 'getApiKey',
        userId,
        error: err.message,
        duration,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return { success: false, message: '获取失败，请稍后重试' };
    }
  }

  /**
   * 更新API Key
   *
   * 功能描述：
   * 更新用户的Zulip API Key
   *
   * @param userId 用户ID
   * @param newApiKey 新的API Key
   * @param metadata 可选的元数据
   * @returns Promise<StoreApiKeyResult> 更新结果
   */
  async updateApiKey(
    userId: string,
    newApiKey: string,
    metadata?: { ipAddress?: string; userAgent?: string }
  ): Promise<StoreApiKeyResult> {
    this.logger.log(`开始更新API Key: ${userId}`);

    try {
      // 1. 检查原API Key是否存在
      const storageKey = `${this.API_KEY_PREFIX}${userId}`;
      const existingData = await this.redisService.get(storageKey);

      if (!existingData) {
        // 如果不存在，则创建新的
        return this.storeApiKey(userId, newApiKey, metadata);
      }

      // 2. 验证新API Key格式
      if (!this.isValidApiKeyFormat(newApiKey)) {
        await this.logSecurityEvent({
          eventType: SecurityEventType.INVALID_KEY_FORMAT,
          severity: SecuritySeverity.WARNING,
          userId,
          details: { reason: 'invalid_format', action: 'update' },
          timestamp: new Date(),
          ...metadata,
        });
        return { success: false, message: 'API Key格式无效' };
      }

      // 3. 解析现有数据
      const oldStorageData: EncryptedApiKey = JSON.parse(existingData);

      // 4. 加密新API Key
      const encrypted = this.encrypt(newApiKey);

      // 5. 更新存储数据
      const newStorageData: EncryptedApiKey = {
        encryptedKey: encrypted.encryptedData,
        iv: encrypted.iv,
        authTag: encrypted.authTag,
        createdAt: oldStorageData.createdAt,
        updatedAt: new Date(),
        accessCount: oldStorageData.accessCount,
        lastAccessedAt: oldStorageData.lastAccessedAt,
      };

      await this.redisService.set(storageKey, JSON.stringify(newStorageData));

      // 6. 记录安全日志
      await this.logSecurityEvent({
        eventType: SecurityEventType.API_KEY_UPDATED,
        severity: SecuritySeverity.INFO,
        userId,
        details: {
          action: 'update',
          previousAccessCount: oldStorageData.accessCount,
        },
        timestamp: new Date(),
        ...metadata,
      });

      this.logger.log(`API Key更新成功: ${userId}`);

      return { success: true, message: 'API Key更新成功', userId };

    } catch (error) {
      const err = error as Error;
      this.logger.error('API Key更新失败', {
        operation: 'updateApiKey',
        userId,
        error: err.message,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return { success: false, message: '更新失败，请稍后重试' };
    }
  }

  /**
   * 删除API Key
   *
   * 功能描述：
   * 安全删除用户的API Key
   *
   * @param userId 用户ID
   * @param metadata 可选的元数据
   * @returns Promise<boolean> 是否删除成功
   */
  async deleteApiKey(
    userId: string,
    metadata?: { ipAddress?: string; userAgent?: string }
  ): Promise<boolean> {
    this.logger.log(`开始删除API Key: ${userId}`);

    try {
      const storageKey = `${this.API_KEY_PREFIX}${userId}`;
      await this.redisService.del(storageKey);

      // 记录安全日志
      await this.logSecurityEvent({
        eventType: SecurityEventType.API_KEY_DELETED,
        severity: SecuritySeverity.INFO,
        userId,
        details: { action: 'delete' },
        timestamp: new Date(),
        ...metadata,
      });

      this.logger.log(`API Key删除成功: ${userId}`);

      return true;

    } catch (error) {
      const err = error as Error;
      this.logger.error('API Key删除失败', {
        operation: 'deleteApiKey',
        userId,
        error: err.message,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return false;
    }
  }

  /**
   * 检查API Key是否存在
   *
   * @param userId 用户ID
   * @returns Promise<boolean> 是否存在
   */
  async hasApiKey(userId: string): Promise<boolean> {
    try {
      const storageKey = `${this.API_KEY_PREFIX}${userId}`;
      return await this.redisService.exists(storageKey);
    } catch (error) {
      this.logger.error('检查API Key存在性失败', {
        operation: 'hasApiKey',
        userId,
        error: (error as Error).message,
      });
      return false;
    }
  }

  /**
   * 记录安全事件
   *
   * 功能描述：
   * 记录安全相关的事件到Redis，用于审计和监控
   *
   * @param event 安全事件
   * @returns Promise<void>
   */
  async logSecurityEvent(event: SecurityEvent): Promise<void> {
    try {
      const logKey = `${this.SECURITY_LOG_PREFIX}${event.userId}:${Date.now()}`;
      await this.redisService.setex(
        logKey,
        this.SECURITY_LOG_RETENTION,
        JSON.stringify(event)
      );

      // 根据严重级别记录到应用日志
      const logContext = {
        operation: 'logSecurityEvent',
        eventType: event.eventType,
        severity: event.severity,
        userId: event.userId,
        details: event.details,
        ipAddress: event.ipAddress,
        timestamp: event.timestamp.toISOString(),
      };

      switch (event.severity) {
        case SecuritySeverity.CRITICAL:
          this.logger.error('安全事件 - 严重', logContext);
          break;
        case SecuritySeverity.WARNING:
          this.logger.warn('安全事件 - 警告', logContext);
          break;
        case SecuritySeverity.INFO:
        default:
          this.logger.log('安全事件 - 信息', logContext);
          break;
      }

    } catch (error) {
      this.logger.error('记录安全事件失败', {
        operation: 'logSecurityEvent',
        event,
        error: (error as Error).message,
      });
    }
  }

  /**
   * 记录可疑访问
   *
   * 功能描述：
   * 当检测到异常操作时记录可疑访问事件
   *
   * @param userId 用户ID
   * @param reason 可疑原因
   * @param details 详细信息
   * @param metadata 元数据
   * @returns Promise<void>
   */
  async logSuspiciousAccess(
    userId: string,
    reason: string,
    details: Record<string, any>,
    metadata?: { ipAddress?: string; userAgent?: string }
  ): Promise<void> {
    await this.logSecurityEvent({
      eventType: SecurityEventType.SUSPICIOUS_ACCESS,
      severity: SecuritySeverity.WARNING,
      userId,
      details: {
        reason,
        ...details,
      },
      timestamp: new Date(),
      ...metadata,
    });
  }

  /**
   * 获取用户安全事件历史
   *
   * @param userId 用户ID
   * @param limit 返回数量限制
   * @returns Promise<SecurityEvent[]> 安全事件列表
   */
  async getSecurityEventHistory(userId: string, limit: number = 100): Promise<SecurityEvent[]> {
    // 注意：这是一个简化实现，实际应该使用Redis的有序集合或扫描功能
    // 当前实现仅作为示例
    this.logger.debug('获取安全事件历史', {
      operation: 'getSecurityEventHistory',
      userId,
      limit,
    });

    return [];
  }

  /**
   * 获取API Key统计信息
   *
   * @param userId 用户ID
   * @returns Promise<{exists: boolean, accessCount?: number, lastAccessedAt?: Date, createdAt?: Date}>
   */
  async getApiKeyStats(userId: string): Promise<{
    exists: boolean;
    accessCount?: number;
    lastAccessedAt?: Date;
    createdAt?: Date;
    updatedAt?: Date;
  }> {
    try {
      const storageKey = `${this.API_KEY_PREFIX}${userId}`;
      const data = await this.redisService.get(storageKey);

      if (!data) {
        return { exists: false };
      }

      const storageData: EncryptedApiKey = JSON.parse(data);
      return {
        exists: true,
        accessCount: storageData.accessCount,
        lastAccessedAt: storageData.lastAccessedAt ? new Date(storageData.lastAccessedAt) : undefined,
        createdAt: new Date(storageData.createdAt),
        updatedAt: new Date(storageData.updatedAt),
      };

    } catch (error) {
      this.logger.error('获取API Key统计信息失败', {
        operation: 'getApiKeyStats',
        userId,
        error: (error as Error).message,
      });
      return { exists: false };
    }
  }

  // ==================== 私有方法 ====================

  /**
   * 加密数据
   *
   * @param plaintext 明文
   * @returns 加密结果
   * @private
   */
  private encrypt(plaintext: string): {
    encryptedData: string;
    iv: string;
    authTag: string;
  } {
    const encryptionKey = this.requireEncryptionKey();
    const iv = crypto.randomBytes(this.IV_LENGTH);
    const cipher = crypto.createCipheriv(
      this.ENCRYPTION_ALGORITHM,
      encryptionKey,
      iv
    );

    let encrypted = cipher.update(plaintext, 'utf8', 'hex');
    encrypted += cipher.final('hex');
    const authTag = cipher.getAuthTag();

    return {
      encryptedData: encrypted,
      iv: iv.toString('hex'),
      authTag: authTag.toString('hex'),
    };
  }

  /**
   * 解密数据
   *
   * @param encryptedData 加密数据
   * @param ivHex IV（十六进制）
   * @param authTagHex 认证标签（十六进制）
   * @returns 解密后的明文
   * @private
   */
  private decrypt(encryptedData: string, ivHex: string, authTagHex: string): string {
    const encryptionKey = this.requireEncryptionKey();
    const iv = Buffer.from(ivHex, 'hex');
    const authTag = Buffer.from(authTagHex, 'hex');
    const decipher = crypto.createDecipheriv(
      this.ENCRYPTION_ALGORITHM,
      encryptionKey,
      iv
    );
    decipher.setAuthTag(authTag);

    let decrypted = decipher.update(encryptedData, 'hex', 'utf8');
    decrypted += decipher.final('utf8');

    return decrypted;
  }

  /**
   * 获取已配置的加密密钥。
   *
   * 降级模式允许服务在没有密钥时启动，但涉及Zulip API Key明文的操作仍必须失败，
   * 以避免使用临时密钥导致数据在重启后无法解密。
   */
  private requireEncryptionKey(): Buffer {
    if (!this.encryptionKey) {
      throw new Error(
        'ZULIP_API_KEY_ENCRYPTION_KEY未配置，Zulip API Key加密存取功能不可用',
      );
    }

    return this.encryptionKey;
  }

  /**
   * 验证API Key格式
   *
   * @param apiKey API Key
   * @returns boolean 是否有效
   * @private
   */
  private isValidApiKeyFormat(apiKey: string): boolean {
    // Zulip API Key通常是32字符的字母数字字符串
    // 这里放宽限制以支持不同格式
    if (!apiKey || apiKey.length < 16 || apiKey.length > 128) {
      return false;
    }
    // 只允许字母、数字和一些特殊字符
    return /^[a-zA-Z0-9_-]+$/.test(apiKey);
  }

  /**
   * 检查访问频率限制
   *
   * @param userId 用户ID
   * @returns Promise<{allowed: boolean, currentCount: number}>
   * @private
   */
  private async checkAccessRateLimit(userId: string): Promise<{
    allowed: boolean;
    currentCount: number;
  }> {
    try {
      const rateLimitKey = `${this.ACCESS_COUNT_PREFIX}${userId}`;
      const currentCount = await this.redisService.get(rateLimitKey);
      const count = currentCount ? parseInt(currentCount, 10) : 0;

      if (count >= this.MAX_ACCESS_PER_MINUTE) {
        return { allowed: false, currentCount: count };
      }

      // 增加计数
      if (count === 0) {
        await this.redisService.setex(rateLimitKey, 60, '1');
      } else {
        await this.redisService.incr(rateLimitKey);
      }

      return { allowed: true, currentCount: count + 1 };

    } catch (error) {
      // 频率检查失败时默认允许
      this.logger.warn('访问频率检查失败', {
        operation: 'checkAccessRateLimit',
        userId,
        error: (error as Error).message,
      });
      return { allowed: true, currentCount: 0 };
    }
  }
}
