/**
 * Zulip账号管理核心服务
 *
 * 功能描述：
 * - 自动创建Zulip用户账号
 * - 生成API Key并安全存储
 * - 处理账号创建失败场景
 * - 管理用户账号与外部系统的关联
 *
 * 职责分离：
 * - 账号创建层：处理Zulip用户账号的创建流程
 * - API Key管理层：生成、存储和管理用户API Key
 * - 关联映射层：维护外部账号与Zulip账号的映射关系
 *
 * 主要方法：
 * - createZulipAccount(): 创建新的Zulip用户账号
 * - generateApiKey(): 为用户生成API Key
 * - validateZulipAccount(): 验证Zulip账号有效性
 * - linkExternalAccount(): 关联外部账号与Zulip账号
 *
 * 使用场景：
 * - 用户注册时自动创建Zulip账号
 * - API Key管理和更新
 * - 账号关联和映射存储
 *
 * 最近修改：
 * - 2026-01-12: 代码规范优化 - 修正Core层业务流程描述，将"注册流程"改为"账号创建" (修改者: moyin)
 * - 2026-01-12: 代码规范优化 - 拆分createZulipAccount长方法，提升代码可读性和维护性 (修改者: moyin)
 * - 2026-01-12: 代码规范优化 - 修正注释规范和修改记录格式 (修改者: moyin)
 * - 2026-01-10: 功能完善 - 完善账号创建和API Key管理逻辑 (修改者: moyin)
 * - 2026-01-07: 代码规范优化 - 更新import路径和注释规范 (修改者: moyin)
 *
 * @author moyin
 * @version 1.2.1
 * @since 2025-01-05
 * @lastModified 2026-01-12
 */

import { Injectable, Logger } from '@nestjs/common';
import { ZulipClientConfig } from '../zulip_core.interfaces';
import { DEFAULT_PASSWORD_LENGTH } from '../zulip_core.constants';

/**
 * Zulip账号创建请求接口
 */
export interface CreateZulipAccountRequest {
  email: string;
  fullName: string;
  password?: string;
  shortName?: string;
}

/**
 * Zulip账号创建结果接口
 */
export interface CreateZulipAccountResult {
  success: boolean;
  userId?: number;
  email?: string;
  apiKey?: string;
  error?: string;
  errorCode?: string;
  isExistingUser?: boolean; // 添加字段表示是否是绑定已有账号
}

/**
 * API Key生成结果接口
 */
export interface GenerateApiKeyResult {
  success: boolean;
  apiKey?: string;
  userId?: number;  // 添加 userId，从 profile 中获取
  error?: string;
}

/**
 * 账号验证结果接口
 */
export interface ValidateAccountResult {
  success: boolean;
  isValid?: boolean;
  userInfo?: any;
  error?: string;
}

/**
 * 账号关联信息接口
 */
export interface AccountLinkInfo {
  gameUserId: string;
  zulipUserId: number;
  zulipEmail: string;
  zulipApiKey: string;
  createdAt: Date;
  lastVerified?: Date;
  isActive: boolean;
}

/**
 * Zulip账号管理服务类
 *
 * 职责：
 * - 处理Zulip用户账号的创建和管理
 * - 管理API Key的生成和存储
 * - 维护外部账号与Zulip账号的关联关系
 * - 提供账号验证和状态检查功能
 *
 * 主要方法：
 * - createZulipAccount(): 创建新的Zulip用户账号
 * - generateApiKey(): 为现有用户生成API Key
 * - validateZulipAccount(): 验证Zulip账号有效性
 * - linkExternalAccount(): 建立外部账号与Zulip账号的关联
 * - unlinkExternalAccount(): 解除账号关联
 *
 * 使用场景：
 * - 用户账号创建时自动创建Zulip账号
 * - API Key管理和更新
 * - 账号状态监控和维护
 * - 跨平台账号同步
 */
@Injectable()
export class ZulipAccountService {
  private readonly logger = new Logger(ZulipAccountService.name);
  private adminClient: any = null;
  private readonly accountLinks = new Map<string, AccountLinkInfo>();

  constructor() {
    this.logger.log('ZulipAccountService初始化完成');
  }

  /**
   * 初始化管理员客户端
   *
   * 功能描述：
   * 使用管理员凭证初始化Zulip客户端，用于创建用户账号
   *
   * @param adminConfig 管理员配置
   * @returns Promise<boolean> 是否初始化成功
   */
  async initializeAdminClient(adminConfig: ZulipClientConfig): Promise<boolean> {
    this.logger.log('初始化Zulip管理员客户端', {
      operation: 'initializeAdminClient',
      realm: adminConfig.realm,
      timestamp: new Date().toISOString(),
    });

    try {
      // 动态导入zulip-js
      const zulipInit = await this.loadZulipModule();

      // 创建管理员客户端
      this.adminClient = await zulipInit({
        username: adminConfig.username,
        apiKey: adminConfig.apiKey,
        realm: adminConfig.realm,
      });

      // 验证管理员权限
      const profile = await this.adminClient.users.me.getProfile();

      if (profile.result !== 'success') {
        throw new Error(`管理员客户端验证失败: ${profile.msg || '未知错误'}`);
      }

      this.logger.log('管理员客户端初始化成功', {
        operation: 'initializeAdminClient',
        adminEmail: profile.email,
        isAdmin: profile.is_admin,
        timestamp: new Date().toISOString(),
      });

      return true;

    } catch (error) {
      const err = error as Error;
      this.logger.error('管理员客户端初始化失败', {
        operation: 'initializeAdminClient',
        error: err.message,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return false;
    }
  }

  /**
   * 创建Zulip用户账号
   *
   * 功能描述：
   * 使用管理员权限在Zulip服务器上创建新的用户账号
   *
   * 技术实现：
   * 1. 验证管理员客户端是否已初始化
   * 2. 检查邮箱是否已存在
   * 3. 生成用户密码（如果未提供）
   * 4. 调用Zulip API创建用户
   * 5. 为新用户生成API Key
   * 6. 返回创建结果
   *
   * @param request 账号创建请求
   * @returns Promise<CreateZulipAccountResult> 创建结果
   */
  async createZulipAccount(request: CreateZulipAccountRequest): Promise<CreateZulipAccountResult> {
    const startTime = Date.now();

    this.logger.log('开始创建Zulip账号', {
      operation: 'createZulipAccount',
      email: request.email,
      fullName: request.fullName,
      timestamp: new Date().toISOString(),
    });

    try {
      // 1. 验证请求参数和管理员客户端
      this.validateCreateRequest(request);

      // 2. 检查用户是否已存在，如果存在则绑定
      const existingUserResult = await this.handleExistingUser(request);
      if (existingUserResult) {
        return existingUserResult;
      }

      // 3. 创建新用户
      const newUserResult = await this.createNewZulipUser(request);

      const duration = Date.now() - startTime;
      this.logger.log('Zulip账号创建完成', {
        operation: 'createZulipAccount',
        email: request.email,
        success: newUserResult.success,
        duration,
        timestamp: new Date().toISOString(),
      });

      return newUserResult;

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

      this.logger.error('创建Zulip账号失败', {
        operation: 'createZulipAccount',
        email: request.email,
        error: err.message,
        duration,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return {
        success: false,
        error: err.message,
        errorCode: 'ACCOUNT_CREATION_FAILED',
      };
    }
  }

  /**
   * 验证创建请求参数
   *
   * @param request 账号创建请求
   * @throws Error 当参数无效时
   * @private
   */
  private validateCreateRequest(request: CreateZulipAccountRequest): void {
    // 1. 验证管理员客户端
    if (!this.adminClient) {
      throw new Error('管理员客户端未初始化');
    }

    // 2. 验证请求参数
    if (!request.email || !request.email.trim()) {
      throw new Error('邮箱地址不能为空');
    }

    if (!request.fullName || !request.fullName.trim()) {
      throw new Error('用户全名不能为空');
    }

    // 3. 检查邮箱格式
    if (!this.isValidEmail(request.email)) {
      throw new Error('邮箱格式无效');
    }
  }

  /**
   * 处理已存在的用户
   *
   * @param request 账号创建请求
   * @returns Promise<CreateZulipAccountResult | null> 如果用户已存在返回结果，否则返回null
   * @private
   */
  private async handleExistingUser(request: CreateZulipAccountRequest): Promise<CreateZulipAccountResult | null> {
    const existingUser = await this.checkUserExists(request.email);
    if (!existingUser) {
      return null;
    }

    this.logger.log('用户已存在，绑定已有账号', {
      operation: 'handleExistingUser',
      email: request.email,
    });

    // 尝试获取已有用户的信息
    const userInfo = await this.getExistingUserInfo(request.email);

    // 尝试为已有用户生成API Key（同时可以获取 userId）
    const apiKeyResult = await this.generateApiKeyForUser(request.email, request.password || '');

    // 优先使用 userInfo 中的 userId，其次使用 apiKeyResult 中的 userId
    const finalUserId = userInfo.userId ?? apiKeyResult.userId;

    if (finalUserId === undefined) {
      this.logger.error('用户已存在但无法获取用户ID，绑定失败', {
        operation: 'handleExistingUser',
        email: request.email,
        getUserInfoError: userInfo.error,
        apiKeyError: apiKeyResult.error,
      });

      return {
        success: false,
        error: `用户已存在但无法获取用户ID`,
        errorCode: 'USER_ID_NOT_FOUND',
        isExistingUser: true,
      };
    }

    this.logger.log('Zulip账号绑定成功（已存在）', {
      operation: 'handleExistingUser',
      email: request.email,
      userId: finalUserId,
      hasApiKey: apiKeyResult.success,
      apiKeyError: apiKeyResult.success ? undefined : apiKeyResult.error,
    });

    return {
      success: true,
      userId: finalUserId,
      email: request.email,
      apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
      isExistingUser: true,
    };
  }

  /**
   * 创建新的Zulip用户
   *
   * @param request 账号创建请求
   * @returns Promise<CreateZulipAccountResult> 创建结果
   * @private
   */
  private async createNewZulipUser(request: CreateZulipAccountRequest): Promise<CreateZulipAccountResult> {
    // 1. 生成密码（如果未提供）
    const password = request.password || this.generateRandomPassword();
    const shortName = request.shortName || this.generateShortName(request.email);

    // 2. 创建用户参数
    const createParams = {
      email: request.email,
      password: password,
      full_name: request.fullName,
      short_name: shortName,
    };

    // 3. 调用Zulip API创建用户
    const createResponse = await this.adminClient.users.create(createParams);

    if (createResponse.result !== 'success') {
      return this.handleCreateUserError(createResponse, request, password);
    }

    // 4. 为新用户生成API Key
    const apiKeyResult = await this.generateApiKeyForUser(request.email, password);

    if (!apiKeyResult.success) {
      this.logger.warn('API Key生成失败，但用户已创建', {
        operation: 'createNewZulipUser',
        email: request.email,
        error: apiKeyResult.error,
      });
      return {
        success: true,
        userId: createResponse.user_id,
        email: request.email,
        error: `用户创建成功，但API Key生成失败: ${apiKeyResult.error}`,
        errorCode: 'API_KEY_GENERATION_FAILED',
      };
    }

    this.logger.log('Zulip账号创建成功', {
      operation: 'createNewZulipUser',
      email: request.email,
      userId: createResponse.user_id,
      hasApiKey: !!apiKeyResult.apiKey,
    });

    return {
      success: true,
      userId: createResponse.user_id,
      email: request.email,
      apiKey: apiKeyResult.apiKey,
    };
  }

  /**
   * 处理创建用户时的错误
   *
   * @param createResponse Zulip API响应
   * @param request 原始请求
   * @param password 生成的密码
   * @returns Promise<CreateZulipAccountResult> 处理结果
   * @private
   */
  private async handleCreateUserError(
    createResponse: any,
    request: CreateZulipAccountRequest,
    password: string
  ): Promise<CreateZulipAccountResult> {
    // 检查是否是用户已存在的错误
    if (createResponse.msg && createResponse.msg.includes('already in use')) {
      this.logger.log('用户邮箱已被使用，尝试绑定已有账号', {
        operation: 'handleCreateUserError',
        email: request.email,
        error: createResponse.msg,
      });

      // 尝试获取已有用户信息
      const userInfo = await this.getExistingUserInfo(request.email);

      // 尝试为已有用户生成API Key（同时可以获取 userId）
      const apiKeyResult = await this.generateApiKeyForUser(request.email, password);

      // 优先使用 userInfo 中的 userId，其次使用 apiKeyResult 中的 userId
      const finalUserId = userInfo.userId ?? apiKeyResult.userId;

      if (finalUserId === undefined) {
        this.logger.error('用户已存在但无法获取用户ID，绑定失败', {
          operation: 'handleCreateUserError',
          email: request.email,
          getUserInfoError: userInfo.error,
          apiKeyError: apiKeyResult.error,
        });

        return {
          success: false,
          error: `用户已存在但无法获取用户ID`,
          errorCode: 'USER_ID_NOT_FOUND',
          isExistingUser: true,
        };
      }

      this.logger.log('Zulip账号绑定成功（API创建时发现已存在）', {
        operation: 'handleCreateUserError',
        email: request.email,
        userId: finalUserId,
        hasApiKey: apiKeyResult.success,
      });

      return {
        success: true,
        userId: finalUserId,
        email: request.email,
        apiKey: apiKeyResult.success ? apiKeyResult.apiKey : undefined,
        isExistingUser: true,
      };
    }

    // 其他类型的错误
    this.logger.warn('Zulip用户创建失败', {
      operation: 'handleCreateUserError',
      email: request.email,
      error: createResponse.msg,
    });

    return {
      success: false,
      error: createResponse.msg || '用户创建失败',
      errorCode: 'ZULIP_CREATE_FAILED',
    };
  }

  /**
   * 为用户生成API Key
   *
   * 功能描述：
   * 使用用户凭证获取API Key
   *
   * @param email 用户邮箱
   * @param password 用户密码
   * @returns Promise<GenerateApiKeyResult> 生成结果
   */
  async generateApiKeyForUser(email: string, password: string): Promise<GenerateApiKeyResult> {
    this.logger.log('为用户生成API Key', {
      operation: 'generateApiKeyForUser',
      email,
      timestamp: new Date().toISOString(),
    });

    try {
      // 动态导入zulip-js
      const zulipInit = await this.loadZulipModule();

      // 使用用户凭证获取API Key
      const userClient = await zulipInit({
        username: email,
        password: password,
        realm: this.getRealmFromAdminClient(),
      });

      // 验证客户端并获取API Key
      const profile = await userClient.users.me.getProfile();

      if (profile.result !== 'success') {
        throw new Error(`API Key获取失败: ${profile.msg || '未知错误'}`);
      }

      // 从客户端配置中提取API Key
      const apiKey = userClient.config?.apiKey;

      if (!apiKey) {
        throw new Error('无法从客户端配置中获取API Key');
      }

      this.logger.log('API Key生成成功', {
        operation: 'generateApiKeyForUser',
        email,
        userId: profile.user_id,
        timestamp: new Date().toISOString(),
      });

      return {
        success: true,
        apiKey: apiKey,
        userId: profile.user_id,  // 返回从 profile 获取的 user_id
      };

    } catch (error) {
      const err = error as Error;

      this.logger.error('API Key生成失败', {
        operation: 'generateApiKeyForUser',
        email,
        error: err.message,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return {
        success: false,
        error: err.message,
      };
    }
  }

  /**
   * 验证Zulip账号有效性
   *
   * 功能描述：
   * 验证指定的Zulip账号是否存在且有效
   *
   * @param email 用户邮箱
   * @param apiKey 用户API Key（可选）
   * @returns Promise<ValidateAccountResult> 验证结果
   */
  async validateZulipAccount(email: string, apiKey?: string): Promise<ValidateAccountResult> {
    this.logger.log('验证Zulip账号', {
      operation: 'validateZulipAccount',
      email,
      hasApiKey: !!apiKey,
      timestamp: new Date().toISOString(),
    });

    try {
      if (apiKey) {
        // 使用API Key验证
        const zulipInit = await this.loadZulipModule();
        const userClient = await zulipInit({
          username: email,
          apiKey: apiKey,
          realm: this.getRealmFromAdminClient(),
        });

        const profile = await userClient.users.me.getProfile();

        if (profile.result === 'success') {
          this.logger.log('账号验证成功（API Key）', {
            operation: 'validateZulipAccount',
            email,
            userId: profile.user_id,
          });

          return {
            success: true,
            isValid: true,
            userInfo: profile,
          };
        } else {
          return {
            success: true,
            isValid: false,
            error: profile.msg || 'API Key验证失败',
          };
        }
      } else {
        // 仅检查用户是否存在
        const userExists = await this.checkUserExists(email);

        this.logger.log('账号存在性检查完成', {
          operation: 'validateZulipAccount',
          email,
          exists: userExists,
        });

        return {
          success: true,
          isValid: userExists,
        };
      }

    } catch (error) {
      const err = error as Error;

      this.logger.error('账号验证失败', {
        operation: 'validateZulipAccount',
        email,
        error: err.message,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return {
        success: false,
        error: err.message,
      };
    }
  }

  /**
   * 关联游戏账号与Zulip账号
   *
   * 功能描述：
   * 建立游戏用户ID与Zulip账号的映射关系
   *
   * @param gameUserId 游戏用户ID
   * @param zulipUserId Zulip用户ID
   * @param zulipEmail Zulip邮箱
   * @param zulipApiKey Zulip API Key
   * @returns Promise<boolean> 是否关联成功
   */
  async linkGameAccount(
    gameUserId: string,
    zulipUserId: number,
    zulipEmail: string,
    zulipApiKey: string,
  ): Promise<boolean> {
    this.logger.log('关联游戏账号与Zulip账号', {
      operation: 'linkGameAccount',
      gameUserId,
      zulipUserId,
      zulipEmail,
      timestamp: new Date().toISOString(),
    });

    try {
      // 验证参数
      if (!gameUserId || !zulipUserId || !zulipEmail || !zulipApiKey) {
        throw new Error('关联参数不完整');
      }

      // 创建关联信息
      const linkInfo: AccountLinkInfo = {
        gameUserId,
        zulipUserId,
        zulipEmail,
        zulipApiKey,
        createdAt: new Date(),
        isActive: true,
      };

      // 存储关联信息（实际项目中应存储到数据库）
      this.accountLinks.set(gameUserId, linkInfo);

      this.logger.log('账号关联成功', {
        operation: 'linkGameAccount',
        gameUserId,
        zulipUserId,
        zulipEmail,
        timestamp: new Date().toISOString(),
      });

      return true;

    } catch (error) {
      const err = error as Error;

      this.logger.error('账号关联失败', {
        operation: 'linkGameAccount',
        gameUserId,
        zulipUserId,
        error: err.message,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return false;
    }
  }

  /**
   * 解除游戏账号与Zulip账号的关联
   *
   * @param gameUserId 游戏用户ID
   * @returns Promise<boolean> 是否解除成功
   */
  async unlinkGameAccount(gameUserId: string): Promise<boolean> {
    this.logger.log('解除账号关联', {
      operation: 'unlinkGameAccount',
      gameUserId,
      timestamp: new Date().toISOString(),
    });

    try {
      const linkInfo = this.accountLinks.get(gameUserId);

      if (linkInfo) {
        linkInfo.isActive = false;
        this.accountLinks.delete(gameUserId);

        this.logger.log('账号关联解除成功', {
          operation: 'unlinkGameAccount',
          gameUserId,
          zulipEmail: linkInfo.zulipEmail,
        });
      }

      return true;

    } catch (error) {
      const err = error as Error;

      this.logger.error('解除账号关联失败', {
        operation: 'unlinkGameAccount',
        gameUserId,
        error: err.message,
        timestamp: new Date().toISOString(),
      }, err.stack);

      return false;
    }
  }

  /**
   * 获取游戏账号的Zulip关联信息
   *
   * @param gameUserId 游戏用户ID
   * @returns AccountLinkInfo | null 关联信息
   */
  getAccountLink(gameUserId: string): AccountLinkInfo | null {
    return this.accountLinks.get(gameUserId) || null;
  }

  /**
   * 获取所有账号关联信息
   *
   * @returns AccountLinkInfo[] 所有关联信息
   */
  getAllAccountLinks(): AccountLinkInfo[] {
    return Array.from(this.accountLinks.values()).filter(link => link.isActive);
  }

  /**
   * 获取已有用户信息
   *
   * 功能描述：
   * 获取Zulip服务器上已存在用户的详细信息
   *
   * @param email 用户邮箱
   * @returns Promise<{success: boolean, userId?: number, userInfo?: any, error?: string}> 用户信息
   * @private
   */
  private async getExistingUserInfo(email: string): Promise<{
    success: boolean;
    userId?: number;
    userInfo?: any;
    error?: string;
  }> {
    this.logger.log('获取已有用户信息', {
      operation: 'getExistingUserInfo',
      email,
    });

    try {
      if (!this.adminClient) {
        throw new Error('管理员客户端未初始化');
      }

      // 获取所有用户列表
      const usersResponse = await this.adminClient.users.retrieve();

      if (usersResponse.result === 'success') {
        const users = usersResponse.members || [];
        const existingUser = users.find((user: any) => user.email === email);

        if (existingUser) {
          this.logger.log('找到已有用户信息', {
            operation: 'getExistingUserInfo',
            email,
            userId: existingUser.user_id,
            fullName: existingUser.full_name,
          });

          return {
            success: true,
            userId: existingUser.user_id,
            userInfo: existingUser,
          };
        } else {
          return {
            success: false,
            error: '用户不存在',
          };
        }
      } else {
        throw new Error(usersResponse.msg || '获取用户列表失败');
      }

    } catch (error) {
      const err = error as Error;
      this.logger.error('获取已有用户信息失败', {
        operation: 'getExistingUserInfo',
        email,
        error: err.message,
      }, err.stack);

      return {
        success: false,
        error: err.message,
      };
    }
  }

  /**
   * 检查用户是否已存在
   *
   * @param email 用户邮箱
   * @returns Promise<boolean> 用户是否存在
   * @private
   */
  private async checkUserExists(email: string): Promise<boolean> {
    try {
      if (!this.adminClient) {
        return false;
      }

      // 获取所有用户列表
      const usersResponse = await this.adminClient.users.retrieve();

      if (usersResponse.result === 'success') {
        const users = usersResponse.members || [];
        return users.some((user: any) => user.email === email);
      }

      return false;

    } catch (error) {
      const err = error as Error;
      this.logger.warn('检查用户存在性失败', {
        operation: 'checkUserExists',
        email,
        error: err.message,
      });
      return false;
    }
  }

  /**
   * 验证邮箱格式
   *
   * @param email 邮箱地址
   * @returns boolean 是否为有效邮箱
   * @private
   */
  private isValidEmail(email: string): boolean {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(email);
  }

  /**
   * 生成随机密码
   *
   * @returns string 随机密码
   * @private
   */
  private generateRandomPassword(): string {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*';
    let password = '';
    for (let i = 0; i < DEFAULT_PASSWORD_LENGTH; i++) {
      password += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return password;
  }

  /**
   * 从邮箱生成短名称
   *
   * @param email 邮箱地址
   * @returns string 短名称
   * @private
   */
  private generateShortName(email: string): string {
    const localPart = email.split('@')[0];
    // 移除特殊字符，只保留字母数字和下划线
    return localPart.replace(/[^a-zA-Z0-9_]/g, '').toLowerCase();
  }

  /**
   * 从管理员客户端获取Realm
   *
   * @returns string Realm URL
   * @private
   */
  private getRealmFromAdminClient(): string {
    if (!this.adminClient || !this.adminClient.config) {
      throw new Error('管理员客户端未初始化或配置缺失');
    }
    return this.adminClient.config.realm;
  }

  /**
   * 动态加载zulip-js模块
   *
   * @returns Promise<any> zulip-js初始化函数
   * @private
   */
  private async loadZulipModule(): Promise<any> {
    try {
      // 使用动态导入加载zulip-js
      const zulipModule = await import('zulip-js');
      return zulipModule.default || zulipModule;
    } catch (error) {
      const err = error as Error;
      this.logger.error('加载zulip-js模块失败', {
        operation: 'loadZulipModule',
        error: err.message,
        timestamp: new Date().toISOString(),
      }, err.stack);
      throw new Error(`加载zulip-js模块失败: ${err.message}`);
    }
  }
}