/**
 * NIM 在线状态管理器
 * 负责订阅和管理用户的在线状态
 * 
 * 功能：
 * 1. 订阅用户在线状态
 * 2. 监听在线状态变化事件
 * 3. 批量订阅/取消订阅
 * 4. 本地缓存在线状态
 */

const EventEmitter = require('./event-emitter.js');

class NimPresenceManager extends EventEmitter {
  constructor() {
    super();
    this.nim = null;
    this.presenceCache = new Map(); // userId -> { online: boolean, lastUpdateTime: number }
    this.subscribed = new Set(); // 已订阅的用户ID集合
    this.initialized = false;
  }

  /**
   * 初始化在线状态管理器
   * @param {Object} nim - NIM 实例
   */
  init(nim) {
    if (this.initialized) {
      console.log('⚠️ NIM 在线状态管理器已初始化');
      return;
    }

    if (!nim || !nim.V2NIMSubscriptionService) {
      console.error('❌ NIM 实例或订阅服务未初始化');
      return;
    }

    this.nim = nim;
    this.setupEventListeners();
    this.initialized = true;
    console.log('✅ NIM 在线状态管理器初始化成功');
  }

  /**
   * 设置事件监听器
   * 参考官方文档: https://doc.yunxin.163.com/messaging2/guide/DA0MjM3NTk?platform=client
   */
  setupEventListeners() {
    try {
      // 使用 .on() 方法注册监听器（与其他服务保持一致）
      this.nim.V2NIMSubscriptionService.on('onUserStatusChanged', (userStatusList) => {
        this.handleUserStatusChanged(userStatusList);
      });

      console.log('✅ 在线状态监听器已注册');
    } catch (error) {
      console.error('❌ 注册在线状态监听器失败:', error);
    }
  }

  /**
   * 处理用户状态变化事件
   * @param {Array} userStatusList - 用户状态列表，数组元素为 V2NIMUserStatus 对象
   * 
   * V2NIMUserStatus 结构参考 (官方文档):
   * {
   *   accountId: string,              // 用户账号ID (必填)
   *   statusType: number,             // 状态类型 (必填):
   *                                   //   0: 未知
   *                                   //   1: 登录 (在线)
   *                                   //   2: 登出 (离线)
   *                                   //   3: 断开连接 (离线)
   *                                   //   10000+: 自定义状态
   *   clientType: V2NIMLoginClientType, // 终端类型 (必填)
   *   publishTime: number,            // 发布时间戳 (必填)
   *   uniqueId: string,               // 唯一ID (可选)
   *   extension: string,              // 扩展字段 (可选)
   *   serverExtension: string         // 服务端扩展 (可选)
   * }
   * 
   * 参考: https://doc.yunxin.163.com/messaging2/client-apis/DAxNjk0Mzc?platform=client#V2NIMUserStatus
   */
  handleUserStatusChanged(userStatusList) {
    if (!Array.isArray(userStatusList)) {
      return;
    }

    userStatusList.forEach(status => {
      const userId = status.accountId;
      if (!userId) {
        console.warn('⚠️ 用户状态缺少 accountId');
        return;
      }

      // 转换 statusType 为数字（兼容字符串或数字）
      const statusTypeNum = typeof status.statusType === 'number' 
        ? status.statusType 
        : parseInt(status.statusType, 10);
      
      // statusType === 1 表示在线
      const isOnline = statusTypeNum === 1;

      // 更新缓存
      this.presenceCache.set(userId, {
        online: isOnline,
        lastUpdateTime: Date.now(),
        statusType: statusTypeNum,
        clientType: status.clientType || null,
        publishTime: status.publishTime || 0,
        uniqueId: status.uniqueId || '',
        extension: status.extension || '',
        serverExtension: status.serverExtension || ''
      });

      // 触发状态变化事件
      this.emit('presence_changed', {
        userId,
        isOnline,
        statusType: statusTypeNum,
        clientType: status.clientType || null,
        publishTime: status.publishTime || 0,
        uniqueId: status.uniqueId || '',
        extension: status.extension || '',
        serverExtension: status.serverExtension || ''
      });
    });
  }

  /**
   * 订阅用户在线状态
   * @param {Array<string>} userIds - 用户ID列表
   * @param {number} expiry - 订阅有效期（秒），默认 7 天，范围 60~2592000
   * @param {boolean} immediateSync - 是否立即同步状态值，默认 true (改为true以便立即获取状态)
   * @returns {Promise<void>}
   */
  async subscribe(userIds, expiry = 7 * 24 * 3600, immediateSync = true) {
    if (!this.initialized || !this.nim) {
      console.error('❌ NIM 在线状态管理器未初始化');
      return;
    }

    if (!Array.isArray(userIds) || userIds.length === 0) {
      console.warn('⚠️ 订阅用户列表为空');
      return;
    }

    // 过滤已订阅的用户
    const newUserIds = userIds.filter(id => !this.subscribed.has(id));
    if (newUserIds.length === 0) {
      console.log('📝 所有用户已订阅，无需重复订阅');
      return;
    }

    // 限制单次最多 100 个用户
    if (newUserIds.length > 100) {
      console.warn(`⚠️ 单次订阅最多 100 个用户，当前 ${newUserIds.length} 个，将分批订阅`);
      const batches = [];
      for (let i = 0; i < newUserIds.length; i += 100) {
        batches.push(newUserIds.slice(i, i + 100));
      }
      
      for (const batch of batches) {
        await this.subscribe(batch, expiry, immediateSync);
      }
      return;
    }

    try {
      // 调用 NIM SDK 订阅接口
      const option = {
        accountIds: newUserIds,
        duration: expiry,
        immediateSync: immediateSync
      };
      
      const result = await this.nim.V2NIMSubscriptionService.subscribeUserStatus(option);
      
      // 如果 immediateSync=true，SDK 可能会立即返回用户状态列表
      if (result && Array.isArray(result) && result.length > 0) {
        this.handleUserStatusChanged(result);
      } else if (result && result.statusList && Array.isArray(result.statusList)) {
        this.handleUserStatusChanged(result.statusList);
      }

      // 记录已订阅
      newUserIds.forEach(id => this.subscribed.add(id));

      console.log(`✅ 已订阅 ${newUserIds.length} 个用户的在线状态`);
    } catch (error) {
      console.error('❌ 订阅用户在线状态失败:', error);
      throw error;
    }
  }

  /**
   * 取消订阅用户在线状态
   * @param {Array<string>} userIds - 用户ID列表
   * @returns {Promise<void>}
   */
  async unsubscribe(userIds) {
    if (!this.initialized || !this.nim) {
      console.error('❌ NIM 在线状态管理器未初始化');
      return;
    }

    if (!Array.isArray(userIds) || userIds.length === 0) {
      console.warn('⚠️ 取消订阅用户列表为空');
      return;
    }

    try {
      console.log(`📡 取消订阅用户在线状态: ${userIds.length} 个用户`);

      // 调用 NIM SDK 取消订阅接口
      // 参考: https://doc.yunxin.163.com/messaging2/client-apis/zY2MzAxNjQ?platform=client
      const option = {
        accountIds: userIds
      };
      
      await this.nim.V2NIMSubscriptionService.unsubscribeUserStatus(option);

      // 从已订阅集合中移除
      userIds.forEach(id => {
        this.subscribed.delete(id);
        this.presenceCache.delete(id);
      });

      console.log(`✅ 成功取消订阅 ${userIds.length} 个用户的在线状态`);
    } catch (error) {
      console.error('❌ 取消订阅用户在线状态失败:', error);
      throw error;
    }
  }

  /**
   * 批量订阅会话列表中的用户
   * @param {Array} conversations - 会话列表
   * @returns {Promise<void>}
   */
  async subscribeConversations(conversations) {
    if (!Array.isArray(conversations) || conversations.length === 0) {
      return;
    }

    // 提取单聊用户ID（过滤群聊）
    const userIds = conversations
      .filter(conv => {
        // 单聊类型判断: type === 'single' 或 type === 0 或 chatType === 0
        return conv.type === 'single' || conv.type === 0 || conv.chatType === 0;
      })
      .map(conv => {
        // 优先使用 targetId，如果没有则从 conversationId 解析
        let userId = conv.targetId;
        
        if (!userId && conv.conversationId && typeof conv.conversationId === 'string') {
          // conversationId 格式: accountId|type|targetId
          const parts = conv.conversationId.split('|');
          userId = parts.length === 3 ? parts[2] : null;
        }
        
        return userId;
      })
      .filter(Boolean);

    if (userIds.length > 0) {
      // immediateSync=true 确保首次订阅时立即返回在线状态
      await this.subscribe(userIds, 7 * 24 * 3600, true);
    }
  }

  /**
   * 获取用户在线状态（从缓存）
   * @param {string} userId - 用户ID
   * @returns {Object|null} - { online: boolean, lastUpdateTime: number }
   */
  getUserPresence(userId) {
    return this.presenceCache.get(userId) || null;
  }

  /**
   * 批量获取用户在线状态
   * @param {Array<string>} userIds - 用户ID列表
   * @returns {Object} - { userId: { online: boolean, lastUpdateTime: number } }
   */
  getBatchUserPresence(userIds) {
    const result = {};
    userIds.forEach(userId => {
      const presence = this.getUserPresence(userId);
      if (presence) {
        result[userId] = presence;
      }
    });
    return result;
  }

  /**
   * 清空缓存
   */
  clearCache() {
    this.presenceCache.clear();
    this.subscribed.clear();
    console.log('🗑️ 已清空在线状态缓存');
  }

  /**
   * 检查管理器是否已初始化
   * @returns {Boolean} 是否已初始化
   */
  getInitStatus() {
    return this.initialized && this.nim !== null;
  }

  /**
   * 销毁管理器
   * 参考官方文档: https://doc.yunxin.163.com/messaging2/guide/DA0MjM3NTk?platform=client
   */
  destroy() {
    if (this.nim && this.nim.V2NIMSubscriptionService) {
      try {
        // 使用 .off() 方法移除监听器
        this.nim.V2NIMSubscriptionService.off('onUserStatusChanged');
        console.log('✅ 已移除在线状态监听器');
      } catch (error) {
        console.error('❌ 移除在线状态监听器失败:', error);
      }
    }

    this.clearCache();
    this.nim = null;
    this.initialized = false;
    console.log('🔚 NIM 在线状态管理器已销毁');
  }
}

// 导出单例
const nimPresenceManager = new NimPresenceManager();
module.exports = nimPresenceManager;
