/**
 * Zulip账号关联服务（内存版本）
 * 
 * 功能描述：
 * - 提供Zulip账号关联的内存存储数据访问服务
 * - 用于开发和测试环境，无需数据库依赖
 * - 实现与数据库版本相同的数据访问接口
 * - 支持数据导入导出和测试数据管理
 * 
 * 职责分离：
 * - 数据访问：通过内存Repository提供数据持久化
 * - 接口兼容：与数据库版本保持完全一致的API接口
 * - 测试支持：提供测试环境的数据管理功能
 * 
 * 注意：业务逻辑已转移到 src/core/zulip_core/services/zulip_accounts_business.service.ts
 * 
 * 最近修改：
 * - 2026-01-15: 代码规范优化 - 清理未使用的导入ConflictException和NotFoundException (修改者: moyin)
 * - 2026-01-12: 架构优化 - 移除业务逻辑，转移到zulip_core业务服务 (修改者: moyin)
 * - 2026-01-12: 代码质量优化 - 修复导入语句，添加缺失的AppLoggerService导入 (修改者: moyin)
 * - 2026-01-12: 代码质量优化 - 修复logger初始化问题，统一使用AppLoggerService (修改者: moyin)
 * - 2026-01-12: 代码质量优化 - 完成所有性能监控代码优化，统一使用createPerformanceMonitor方法 (修改者: moyin)
 * 
 * @author angjustinl
 * @version 2.0.1
 * @since 2025-01-07
 * @lastModified 2026-01-15
 */

import { Injectable, Inject } from '@nestjs/common';
import { BaseZulipAccountsService } from './base_zulip_accounts.service';
import { ZulipAccountsMemoryRepository } from './zulip_accounts_memory.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 ZulipAccountsMemoryService extends BaseZulipAccountsService {
  constructor(
    @Inject('ZulipAccountsRepository')
    private readonly repository: ZulipAccountsMemoryRepository,
    @Inject(AppLoggerService) logger: AppLoggerService,
  ) {
    super(logger, 'ZulipAccountsMemoryService');
    this.logger.info('ZulipAccountsMemoryService初始化完成', {
      module: 'ZulipAccountsMemoryService',
      operation: 'constructor'
    });
  }

  /**
   * 创建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',
      });

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

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

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

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

      const result = this.toResponseDto(account);
      monitor.success({ found: true });
      return result;

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

  /**
   * 根据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 memoryService.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邮箱查找关联
   * 
   * @param zulipEmail Zulip邮箱
   * @param includeGameUser 是否包含游戏用户信息（内存模式忽略）
   * @returns Promise<ZulipAccountResponseDto | null> 关联记录或null
   */
  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查找关联
   * 
   * @param id 关联记录ID
   * @param includeGameUser 是否包含游戏用户信息（内存模式忽略）
   * @returns Promise<ZulipAccountResponseDto> 关联记录
   */
  async findById(id: string, includeGameUser: boolean = false): Promise<ZulipAccountResponseDto> {
    this.logStart('根据ID查找关联', { id });

    try {
      const account = await this.repository.findById(this.parseId(id), includeGameUser);
      
      const result = account ? this.toResponseDto(account) : null;
      this.logSuccess('根据ID查找关联', { id, found: !!account });
      return result;

    } catch (error) {
      this.handleDataAccessError(error, '根据ID查找关联', { id });
    }
  }

  /**
   * 更新Zulip账号关联
   * 
   * @param id 关联记录ID
   * @param updateDto 更新数据
   * @returns Promise<ZulipAccountResponseDto> 更新后的记录
   */
  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更新关联
   * 
   * @param gameUserId 游戏用户ID
   * @param updateDto 更新数据
   * @returns Promise<ZulipAccountResponseDto> 更新后的记录
   */
  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),
      };
    }
  }

  /**
   * 获取账号状态统计
   * 
   * @returns Promise<ZulipAccountStatsResponseDto> 状态统计
   */
  async getStatusStatistics(): Promise<ZulipAccountStatsResponseDto> {
    this.logStart('获取账号状态统计');

    try {
      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),
      };

      this.logSuccess('获取账号状态统计', result);

      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,
    };
  }
}