/**
 * Zulip账号关联服务（数据库版本）
 * 
 * 功能描述：
 * - 提供Zulip账号关联的数据访问服务
 * - 封装Repository层的数据操作
 * - 提供基础的CRUD操作接口
 * - 支持缓存机制提升查询性能
 * 
 * 职责分离：
 * - 数据访问：封装Repository层的数据操作
 * - 缓存管理：管理数据缓存策略
 * - DTO转换：实体对象与响应DTO之间的转换
 * - 日志记录：记录数据访问操作日志
 * 
 * 注意：业务逻辑已转移到 src/core/zulip_core/services/zulip_accounts_business.service.ts
 * 
 * 最近修改：
 * - 2026-01-15: 代码规范优化 - 清理未使用的导入NotFoundException (修改者: moyin)
 * - 2026-01-12: 代码规范优化 - 修复依赖注入配置，添加@Inject装饰器确保正确的参数注入 (修改者: moyin)
 * - 2026-01-12: 功能修改 - 优化create方法错误处理，正确转换重复创建错误为ConflictException (修改者: moyin)
 * - 2026-01-12: 架构优化 - 移除业务逻辑，转移到zulip_core业务服务 (修改者: moyin)
 * - 2026-01-12: 代码质量优化 - 清理重复导入，统一使用@Inject装饰器 (修改者: moyin)
 * 
 * @author angjustinl
 * @version 2.1.1
 * @since 2025-01-07
 * @lastModified 2026-01-15
 */

import { Injectable, Inject, ConflictException } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { BaseZulipAccountsService } from './base_zulip_accounts.service';
import { ZulipAccountsRepository } from './zulip_accounts.repository';
import { ZulipAccounts } from './zulip_accounts.entity';
import { AppLoggerService } from '../../utils/logger/logger.service';
import {
  DEFAULT_VERIFICATION_MAX_AGE,
  DEFAULT_MAX_RETRY_COUNT,
} from './zulip_accounts.constants';
import {
  CreateZulipAccountDto,
  UpdateZulipAccountDto,
  QueryZulipAccountDto,
  ZulipAccountResponseDto,
  ZulipAccountListResponseDto,
  ZulipAccountStatsResponseDto,
  BatchUpdateResponseDto,
  VerifyAccountResponseDto,
} from './zulip_accounts.dto';

@Injectable()
export class ZulipAccountsService extends BaseZulipAccountsService {
  // 缓存键前缀
  private static readonly CACHE_PREFIX = 'zulip_accounts';
  private static readonly CACHE_TTL = 300; // 5分钟缓存
  private static readonly STATS_CACHE_TTL = 60; // 统计数据1分钟缓存

  constructor(
    @Inject(ZulipAccountsRepository) private readonly repository: ZulipAccountsRepository,
    @Inject(AppLoggerService) logger: AppLoggerService,
    @Inject(CACHE_MANAGER) private readonly cacheManager: any,
  ) {
    super(logger, 'ZulipAccountsService');
    this.logger.info('ZulipAccountsService初始化完成', {
      module: 'ZulipAccountsService',
      operation: 'constructor',
      cacheEnabled: !!this.cacheManager
    });
  }

  /**
   * 创建Zulip账号关联
   * 
   * 数据访问逻辑：
   * 1. 接收创建请求数据
   * 2. 将字符串类型的gameUserId转换为BigInt类型
   * 3. 调用Repository层创建账号关联记录
   * 4. 清除相关缓存确保数据一致性
   * 5. 将实体对象转换为响应DTO返回
   * 
   * @param createDto 创建数据，包含游戏用户ID、Zulip用户信息等
   * @returns Promise<ZulipAccountResponseDto> 创建的关联记录DTO
   * @throws 数据访问异常
   */
  async create(createDto: CreateZulipAccountDto): Promise<ZulipAccountResponseDto> {
    const monitor = this.createPerformanceMonitor('创建Zulip账号关联', { 
      gameUserId: createDto.gameUserId 
    });

    try {
      const account = await this.repository.create({
        gameUserId: this.parseGameUserId(createDto.gameUserId),
        zulipUserId: createDto.zulipUserId,
        zulipEmail: createDto.zulipEmail,
        zulipFullName: createDto.zulipFullName,
        zulipApiKeyEncrypted: createDto.zulipApiKeyEncrypted,
        status: createDto.status || 'active',
      });

      // 清除相关缓存
      await this.clearRelatedCache(createDto.gameUserId, createDto.zulipUserId, createDto.zulipEmail);

      const result = this.toResponseDto(account);
      monitor.success({ 
        accountId: account.id.toString(),
        status: account.status
      });

      return result;

    } catch (error) {
      // 检查是否是重复创建错误，转换为ConflictException
      const errorMessage = this.formatError(error);
      if (errorMessage.includes('already has a Zulip account') || 
          errorMessage.includes('duplicate') || 
          errorMessage.includes('unique constraint')) {
        const conflictError = new ConflictException(`游戏用户 ${createDto.gameUserId} 已存在Zulip账号关联`);
        monitor.error(conflictError);
        throw conflictError;
      } else {
        monitor.error(error);
        throw error;
      }
    }
  }

  /**
   * 根据游戏用户ID查找关联（带缓存）
   * 
   * 数据访问逻辑：
   * 1. 构建缓存键并尝试从缓存获取数据
   * 2. 如果缓存命中，记录日志并返回缓存数据
   * 3. 如果缓存未命中，从数据库查询数据
   * 4. 将查询结果存入缓存，设置合适的TTL
   * 5. 记录查询日志和性能指标
   * 6. 将实体对象转换为响应DTO返回
   * 
   * @param gameUserId 游戏用户ID，字符串格式
   * @param includeGameUser 是否包含游戏用户信息，默认false
   * @returns Promise<ZulipAccountResponseDto | null> 关联记录DTO或null
   * @throws BadRequestException 当查询参数无效或系统异常时
   * 
   * @example
   * ```typescript
   * const account = await service.findByGameUserId('12345', true);
   * if (account) {
   *   console.log('找到关联:', account.zulipEmail);
   * }
   * ```
   */
  async findByGameUserId(gameUserId: string, includeGameUser: boolean = false): Promise<ZulipAccountResponseDto | null> {
    const cacheKey = this.buildCacheKey('game_user', gameUserId, includeGameUser);
    
    try {
      // 尝试从缓存获取
      const cached = await this.cacheManager.get(cacheKey) as ZulipAccountResponseDto;
      if (cached) {
        this.logger.debug('缓存命中', {
          module: this.moduleName,
          operation: 'findByGameUserId',
          gameUserId,
          cacheKey
        });
        return cached;
      }

      // 缓存未命中，从数据库查询
      const monitor = this.createPerformanceMonitor('根据游戏用户ID查找关联', { gameUserId });
      
      const account = await this.repository.findByGameUserId(this.parseGameUserId(gameUserId), includeGameUser);
      
      if (!account) {
        this.logger.debug('未找到Zulip账号关联', {
          module: this.moduleName,
          operation: 'findByGameUserId',
          gameUserId
        });
        monitor.success({ found: false });
        return null;
      }

      const result = this.toResponseDto(account);
      
      // 存入缓存
      await this.cacheManager.set(cacheKey, result, ZulipAccountsService.CACHE_TTL);
      
      monitor.success({ found: true, cached: true });
      return result;

    } catch (error) {
      this.handleDataAccessError(error, '根据游戏用户ID查找关联', { gameUserId });
    }
  }

  /**
   * 根据Zulip用户ID查找关联
   * 
   * 数据访问逻辑：
   * 1. 记录查询操作开始日志
   * 2. 调用Repository层根据Zulip用户ID查找记录
   * 3. 如果未找到记录，记录调试日志并返回null
   * 4. 如果找到记录，记录成功日志
   * 5. 将实体对象转换为响应DTO返回
   * 6. 捕获异常并进行统一的错误处理
   * 
   * @param zulipUserId Zulip用户ID，数字类型
   * @param includeGameUser 是否包含游戏用户信息，默认false
   * @returns Promise<ZulipAccountResponseDto | null> 关联记录DTO或null
   * @throws BadRequestException 当查询参数无效或系统异常时
   * 
   * @example
   * ```typescript
   * const account = await service.findByZulipUserId(67890);
   * if (account) {
   *   console.log('关联的游戏用户:', account.gameUserId);
   * }
   * ```
   */
  async findByZulipUserId(zulipUserId: number, includeGameUser: boolean = false): Promise<ZulipAccountResponseDto | null> {
    this.logStart('根据Zulip用户ID查找关联', { zulipUserId });

    try {
      const account = await this.repository.findByZulipUserId(zulipUserId, includeGameUser);
      
      if (!account) {
        this.logger.debug('未找到Zulip账号关联', { zulipUserId });
        return null;
      }

      this.logSuccess('根据Zulip用户ID查找关联', { zulipUserId, found: true });
      return this.toResponseDto(account);

    } catch (error) {
      this.handleDataAccessError(error, '根据Zulip用户ID查找关联', { zulipUserId });
    }
  }

  /**
   * 根据Zulip邮箱查找关联
   * 
   * 数据访问逻辑：
   * 1. 记录查询操作开始日志
   * 2. 调用Repository层根据Zulip邮箱查找记录
   * 3. 如果未找到记录，记录调试日志并返回null
   * 4. 如果找到记录，记录成功日志
   * 5. 将实体对象转换为响应DTO返回
   * 6. 捕获异常并进行统一的错误处理
   * 
   * @param zulipEmail Zulip邮箱地址，字符串格式
   * @param includeGameUser 是否包含游戏用户信息，默认false
   * @returns Promise<ZulipAccountResponseDto | null> 关联记录DTO或null
   * @throws BadRequestException 当查询参数无效或系统异常时
   * 
   * @example
   * ```typescript
   * const account = await service.findByZulipEmail('user@example.com');
   * if (account) {
   *   console.log('邮箱对应的用户:', account.zulipFullName);
   * }
   * ```
   */
  async findByZulipEmail(zulipEmail: string, includeGameUser: boolean = false): Promise<ZulipAccountResponseDto | null> {
    this.logStart('根据Zulip邮箱查找关联', { zulipEmail });

    try {
      const account = await this.repository.findByZulipEmail(zulipEmail, includeGameUser);
      
      if (!account) {
        this.logger.debug('未找到Zulip账号关联', { zulipEmail });
        return null;
      }

      this.logSuccess('根据Zulip邮箱查找关联', { zulipEmail, found: true });
      return this.toResponseDto(account);

    } catch (error) {
      this.handleDataAccessError(error, '根据Zulip邮箱查找关联', { zulipEmail });
    }
  }

  /**
   * 根据ID查找关联
   * 
   * 数据访问逻辑：
   * 1. 记录查询操作开始日志
   * 2. 将字符串类型的ID转换为BigInt类型
   * 3. 调用Repository层根据ID查找记录
   * 4. 如果未找到记录，抛出NotFoundException异常
   * 5. 如果找到记录，记录成功日志
   * 6. 将实体对象转换为响应DTO返回
   * 7. 捕获异常并进行统一的错误处理
   * 
   * @param id 关联记录ID，字符串格式
   * @param includeGameUser 是否包含游戏用户信息，默认false
   * @returns Promise<ZulipAccountResponseDto> 关联记录DTO
   * @throws NotFoundException 当记录不存在时
   * @throws BadRequestException 当查询参数无效或系统异常时
   * 
   * @example
   * ```typescript
   * const account = await service.findById('123', true);
   * console.log('找到记录:', account.zulipEmail);
   * ```
   */
  async findById(id: string, includeGameUser: boolean = false): Promise<ZulipAccountResponseDto> {
    const monitor = this.createPerformanceMonitor('根据ID查找关联', { id });

    try {
      const account = await this.repository.findById(this.parseId(id), includeGameUser);
      
      const result = account ? this.toResponseDto(account) : null;
      monitor.success({ found: !!account });
      return result;

    } catch (error) {
      monitor.error(error);
      throw error;
    }
  }

  /**
   * 更新Zulip账号关联
   * 
   * 数据访问逻辑：
   * 1. 记录更新操作开始时间和日志
   * 2. 将字符串类型的ID转换为BigInt类型
   * 3. 调用Repository层执行更新操作
   * 4. 如果记录不存在，抛出NotFoundException异常
   * 5. 记录操作成功日志和耗时
   * 6. 将更新后的实体转换为响应DTO返回
   * 7. 捕获异常并进行统一的错误处理
   * 
   * @param id 关联记录ID，字符串格式
   * @param updateDto 更新数据，包含需要修改的字段
   * @returns Promise<ZulipAccountResponseDto> 更新后的记录DTO
   * @throws NotFoundException 当记录不存在时
   * @throws BadRequestException 当更新数据无效或系统异常时
   * 
   * @example
   * ```typescript
   * const updated = await service.update('123', {
   *   zulipFullName: '新用户名',
   *   status: 'active'
   * });
   * ```
   */
  async update(id: string, updateDto: UpdateZulipAccountDto): Promise<ZulipAccountResponseDto> {
    const monitor = this.createPerformanceMonitor('更新Zulip账号关联', { id });

    try {
      const account = await this.repository.update(this.parseId(id), updateDto);
      
      const result = account ? this.toResponseDto(account) : null;
      monitor.success({ updated: !!account });
      return result;

    } catch (error) {
      monitor.error(error);
      throw error;
    }
  }

  /**
   * 根据游戏用户ID更新关联
   * 
   * 数据访问逻辑：
   * 1. 记录更新操作开始时间和日志
   * 2. 将字符串类型的gameUserId转换为BigInt类型
   * 3. 调用Repository层根据游戏用户ID执行更新
   * 4. 如果记录不存在，抛出NotFoundException异常
   * 5. 记录操作成功日志和耗时
   * 6. 将更新后的实体转换为响应DTO返回
   * 7. 捕获异常并进行统一的错误处理
   * 
   * @param gameUserId 游戏用户ID，字符串格式
   * @param updateDto 更新数据，包含需要修改的字段
   * @returns Promise<ZulipAccountResponseDto> 更新后的记录DTO
   * @throws NotFoundException 当记录不存在时
   * @throws BadRequestException 当更新数据无效或系统异常时
   * 
   * @example
   * ```typescript
   * const updated = await service.updateByGameUserId('12345', {
   *   status: 'suspended',
   *   errorMessage: '账号异常'
   * });
   * ```
   */
  async updateByGameUserId(gameUserId: string, updateDto: UpdateZulipAccountDto): Promise<ZulipAccountResponseDto> {
    const monitor = this.createPerformanceMonitor('根据游戏用户ID更新关联', { gameUserId });

    try {
      const account = await this.repository.updateByGameUserId(this.parseGameUserId(gameUserId), updateDto);
      
      const result = account ? this.toResponseDto(account) : null;
      monitor.success({ updated: !!account });
      return result;

    } catch (error) {
      monitor.error(error);
      throw error;
    }
  }

  /**
   * 删除Zulip账号关联
   * 
   * @param id 关联记录ID
   * @returns Promise<boolean> 是否删除成功
   */
  async delete(id: string): Promise<boolean> {
    const monitor = this.createPerformanceMonitor('删除Zulip账号关联', { id });

    try {
      const result = await this.repository.delete(this.parseId(id));
      
      monitor.success({ deleted: result });
      return result;

    } catch (error) {
      monitor.error(error);
      throw error;
    }
  }

  /**
   * 根据游戏用户ID删除关联
   * 
   * @param gameUserId 游戏用户ID
   * @returns Promise<boolean> 是否删除成功
   */
  async deleteByGameUserId(gameUserId: string): Promise<boolean> {
    const monitor = this.createPerformanceMonitor('根据游戏用户ID删除关联', { gameUserId });

    try {
      const result = await this.repository.deleteByGameUserId(this.parseGameUserId(gameUserId));
      
      monitor.success({ deleted: result });
      return result;

    } catch (error) {
      monitor.error(error);
      throw error;
    }
  }

  /**
   * 查询多个Zulip账号关联
   * 
   * @param queryDto 查询条件
   * @returns Promise<ZulipAccountListResponseDto> 关联记录列表
   */
  async findMany(queryDto: QueryZulipAccountDto = {}): Promise<ZulipAccountListResponseDto> {
    this.logStart('查询多个Zulip账号关联', queryDto);

    try {
      const options = {
        gameUserId: queryDto.gameUserId ? this.parseGameUserId(queryDto.gameUserId) : undefined,
        zulipUserId: queryDto.zulipUserId,
        zulipEmail: queryDto.zulipEmail,
        status: queryDto.status,
        includeGameUser: queryDto.includeGameUser || false,
      };

      const accounts = await this.repository.findMany(options);
      
      this.logSuccess('查询多个Zulip账号关联', { 
        count: accounts.length,
        conditions: queryDto 
      });

      return this.buildListResponse(accounts);

    } catch (error) {
      return {
        accounts: this.handleSearchError(error, '查询多个Zulip账号关联', queryDto),
        total: 0,
        count: 0,
      };
    }
  }

  /**
   * 获取需要验证的账号列表
   * 
   * @param maxAge 最大验证间隔（毫秒），默认24小时
   * @returns Promise<ZulipAccountListResponseDto> 需要验证的账号列表
   */
  async findAccountsNeedingVerification(maxAge: number = DEFAULT_VERIFICATION_MAX_AGE): Promise<ZulipAccountListResponseDto> {
    this.logStart('获取需要验证的账号列表', { maxAge });

    try {
      const accounts = await this.repository.findAccountsNeedingVerification(maxAge);
      
      this.logSuccess('获取需要验证的账号列表', { count: accounts.length });

      return this.buildListResponse(accounts);

    } catch (error) {
      return {
        accounts: this.handleSearchError(error, '获取需要验证的账号列表', { maxAge }),
        total: 0,
        count: 0,
      };
    }
  }

  /**
   * 获取错误状态的账号列表
   * 
   * @param maxRetryCount 最大重试次数，默认3次
   * @returns Promise<ZulipAccountListResponseDto> 错误状态的账号列表
   */
  async findErrorAccounts(maxRetryCount: number = DEFAULT_MAX_RETRY_COUNT): Promise<ZulipAccountListResponseDto> {
    this.logStart('获取错误状态的账号列表', { maxRetryCount });

    try {
      const accounts = await this.repository.findErrorAccounts(maxRetryCount);
      
      this.logSuccess('获取错误状态的账号列表', { count: accounts.length });

      return this.buildListResponse(accounts);

    } catch (error) {
      return {
        accounts: this.handleSearchError(error, '获取错误状态的账号列表', { maxRetryCount }),
        total: 0,
        count: 0,
      };
    }
  }

  /**
   * 批量更新账号状态
   * 
   * @param ids 账号ID列表
   * @param status 新状态
   * @returns Promise<BatchUpdateResponseDto> 批量更新结果
   */
  async batchUpdateStatus(ids: string[], status: 'active' | 'inactive' | 'suspended' | 'error'): Promise<BatchUpdateResponseDto> {
    const monitor = this.createPerformanceMonitor('批量更新账号状态', { count: ids.length, status });

    try {
      const bigintIds = this.parseIds(ids);
      const updatedCount = await this.repository.batchUpdateStatus(bigintIds, status);

      monitor.success({ 
        requestCount: ids.length,
        updatedCount,
        status 
      });

      return {
        success: true,
        updatedCount,
      };

    } catch (error) {
      this.logger.error('批量更新账号状态失败', {
        operation: 'batchUpdateStatus',
        error: this.formatError(error),
        count: ids.length,
        status,
      });

      return {
        success: false,
        updatedCount: 0,
        error: this.formatError(error),
      };
    }
  }

  /**
   * 获取账号状态统计（带缓存）
   * 
   * 数据访问逻辑：
   * 1. 构建统计数据的缓存键
   * 2. 尝试从缓存获取统计数据
   * 3. 如果缓存命中，直接返回缓存数据
   * 4. 如果缓存未命中，从数据库查询统计数据
   * 5. 计算总数并构建完整的统计响应
   * 6. 将统计结果存入缓存，使用较短的TTL
   * 7. 记录操作日志和性能指标
   * 
   * @returns Promise<ZulipAccountStatsResponseDto> 状态统计
   */
  async getStatusStatistics(): Promise<ZulipAccountStatsResponseDto> {
    const cacheKey = this.buildCacheKey('stats');
    
    try {
      // 尝试从缓存获取
      const cached = await this.cacheManager.get(cacheKey) as ZulipAccountStatsResponseDto;
      if (cached) {
        this.logger.debug('统计数据缓存命中', {
          module: this.moduleName,
          operation: 'getStatusStatistics',
          cacheKey
        });
        return cached;
      }

      // 缓存未命中，从数据库查询
      const monitor = this.createPerformanceMonitor('获取账号状态统计');
      
      const statistics = await this.repository.getStatusStatistics();

      const result = {
        active: statistics.active || 0,
        inactive: statistics.inactive || 0,
        suspended: statistics.suspended || 0,
        error: statistics.error || 0,
        total: (statistics.active || 0) + (statistics.inactive || 0) + 
               (statistics.suspended || 0) + (statistics.error || 0),
      };

      // 存入缓存，使用较短的TTL
      await this.cacheManager.set(cacheKey, result, ZulipAccountsService.STATS_CACHE_TTL);
      
      monitor.success({ 
        total: result.total,
        cached: true
      });

      return result;

    } catch (error) {
      this.handleDataAccessError(error, '获取账号状态统计');
    }
  }

  /**
   * 验证账号有效性
   * 
   * @param gameUserId 游戏用户ID
   * @returns Promise<VerifyAccountResponseDto> 验证结果
   */
  async verifyAccount(gameUserId: string): Promise<VerifyAccountResponseDto> {
    const monitor = this.createPerformanceMonitor('验证账号有效性', { gameUserId });

    try {
      // 1. 查找账号关联
      const account = await this.repository.findByGameUserId(this.parseGameUserId(gameUserId));
      
      if (!account) {
        monitor.success({ isValid: false, reason: '账号关联不存在' });
        return {
          success: false,
          isValid: false,
          error: '账号关联不存在',
        };
      }

      // 2. 检查账号状态
      if (account.status !== 'active') {
        monitor.success({ isValid: false, reason: `账号状态为 ${account.status}` });
        return {
          success: true,
          isValid: false,
          error: `账号状态为 ${account.status}`,
        };
      }

      // 3. 更新验证时间
      await this.repository.updateByGameUserId(this.parseGameUserId(gameUserId), {
        lastVerifiedAt: new Date(),
      });

      monitor.success({ isValid: true });

      return {
        success: true,
        isValid: true,
        verifiedAt: new Date().toISOString(),
      };

    } catch (error) {
      this.logger.error('验证账号有效性失败', {
        operation: 'verifyAccount',
        gameUserId,
        error: this.formatError(error),
      });

      return {
        success: false,
        isValid: false,
        error: this.formatError(error),
      };
    }
  }

  /**
   * 检查邮箱是否已存在
   * 
   * @param zulipEmail Zulip邮箱
   * @param excludeId 排除的记录ID
   * @returns Promise<boolean> 是否已存在
   */
  async existsByEmail(zulipEmail: string, excludeId?: string): Promise<boolean> {
    try {
      const excludeBigintId = excludeId ? this.parseId(excludeId) : undefined;
      return await this.repository.existsByEmail(zulipEmail, excludeBigintId);
    } catch (error) {
      this.logger.warn('检查邮箱存在性失败', {
        operation: 'existsByEmail',
        zulipEmail,
        error: this.formatError(error),
      });
      return false;
    }
  }

  /**
   * 检查Zulip用户ID是否已存在
   * 
   * @param zulipUserId Zulip用户ID
   * @param excludeId 排除的记录ID
   * @returns Promise<boolean> 是否已存在
   */
  async existsByZulipUserId(zulipUserId: number, excludeId?: string): Promise<boolean> {
    try {
      const excludeBigintId = excludeId ? this.parseId(excludeId) : undefined;
      return await this.repository.existsByZulipUserId(zulipUserId, excludeBigintId);
    } catch (error) {
      this.logger.warn('检查Zulip用户ID存在性失败', {
        operation: 'existsByZulipUserId',
        zulipUserId,
        error: this.formatError(error),
      });
      return false;
    }
  }

  /**
   * 将实体转换为响应DTO
   * 
   * @param account 账号关联实体
   * @returns ZulipAccountResponseDto 响应DTO
   */
  protected toResponseDto(account: ZulipAccounts): ZulipAccountResponseDto {
    return {
      id: account.id.toString(),
      gameUserId: account.gameUserId.toString(),
      zulipUserId: account.zulipUserId,
      zulipEmail: account.zulipEmail,
      zulipFullName: account.zulipFullName,
      status: account.status,
      lastVerifiedAt: account.lastVerifiedAt?.toISOString(),
      lastSyncedAt: account.lastSyncedAt?.toISOString(),
      errorMessage: account.errorMessage,
      retryCount: account.retryCount,
      createdAt: account.createdAt.toISOString(),
      updatedAt: account.updatedAt.toISOString(),
      gameUser: account.gameUser,
    };
  }

  // ========== 缓存管理方法 ==========

  /**
   * 构建缓存键
   * 
   * @param type 缓存类型
   * @param identifier 标识符
   * @param includeGameUser 是否包含游戏用户信息
   * @returns 缓存键字符串
   * @private
   */
  private buildCacheKey(type: string, identifier?: string, includeGameUser?: boolean): string {
    const parts = [ZulipAccountsService.CACHE_PREFIX, type];
    if (identifier) parts.push(identifier);
    if (includeGameUser) parts.push('with_user');
    return parts.join(':');
  }

  /**
   * 清除相关缓存
   * 
   * 功能描述：
   * 当数据发生变更时，清除相关的缓存项以确保数据一致性
   * 
   * @param gameUserId 游戏用户ID
   * @param zulipUserId Zulip用户ID
   * @param zulipEmail Zulip邮箱
   * @private
   */
  private async clearRelatedCache(gameUserId?: string, zulipUserId?: number, zulipEmail?: string): Promise<void> {
    const keysToDelete: string[] = [];

    // 清除统计缓存
    keysToDelete.push(this.buildCacheKey('stats'));

    // 清除具体记录的缓存
    if (gameUserId) {
      keysToDelete.push(this.buildCacheKey('game_user', gameUserId, false));
      keysToDelete.push(this.buildCacheKey('game_user', gameUserId, true));
    }

    if (zulipUserId) {
      keysToDelete.push(this.buildCacheKey('zulip_user', zulipUserId.toString(), false));
      keysToDelete.push(this.buildCacheKey('zulip_user', zulipUserId.toString(), true));
    }

    if (zulipEmail) {
      keysToDelete.push(this.buildCacheKey('zulip_email', zulipEmail, false));
      keysToDelete.push(this.buildCacheKey('zulip_email', zulipEmail, true));
    }

    // 批量删除缓存
    try {
      await Promise.all(keysToDelete.map(key => this.cacheManager.del(key)));
      
      this.logger.debug('清除相关缓存', {
        module: this.moduleName,
        operation: 'clearRelatedCache',
        keysCount: keysToDelete.length,
        keys: keysToDelete
      });
    } catch (error) {
      this.logger.warn('清除缓存失败', {
        module: this.moduleName,
        operation: 'clearRelatedCache',
        error: this.formatError(error),
        keys: keysToDelete
      });
    }
  }

  /**
   * 清除所有相关缓存
   * 
   * 功能描述：
   * 清除所有与Zulip账号相关的缓存，通常在批量操作后调用
   * 
   * @returns Promise<void>
   */
  async clearAllCache(): Promise<void> {
    try {
      // 这里可以根据实际的缓存实现来清除所有相关缓存
      // 由于cache-manager没有直接的模式匹配删除，我们清除已知的缓存类型
      const commonKeys = [
        this.buildCacheKey('stats'),
        // 可以添加更多已知的缓存键模式
      ];

      await Promise.all(commonKeys.map(key => this.cacheManager.del(key)));
      
      this.logger.info('清除所有缓存完成', {
        module: this.moduleName,
        operation: 'clearAllCache',
        keysCount: commonKeys.length
      });
    } catch (error) {
      this.logger.warn('清除所有缓存失败', {
        module: this.moduleName,
        operation: 'clearAllCache',
        error: this.formatError(error)
      });
    }
  }
}