/**
 * TIM在线状态管理器 + WebSocket聊天管理器
 * 统一管理WebSocket连接、心跳、在线状态、聊天消息
 */

import timManager from './tim-manager.js';
import TIM from 'tim-wx-sdk';

// WebSocket/TIM 调试日志开关
const DEBUG_WS = false;

class TIMPresenceManager {
  constructor() {
    this.ws = null;
    this.heartbeatTimer = null;
    this.reconnectTimer = null;
    this.heartbeatInterval = 30000; // 30秒心跳
    this.reconnectInterval = 5000; // 5秒重连
    this.isConnected = false;
    this.userId = null;
    this.statusCallbacks = new Map(); // 存储状态变化回调
    this.onlineStatusCache = new Map(); // 缓存在线状态
    this.wsUrl = 'ws://localhost:8083/ws/chat';
    
    // TIM 状态监听器引用（用于清理）
    this.timStatusListener = null;
    this.timConnectListener = null;
    
    // 聊天消息相关
    this.messageQueue = []; // 消息队列（断线时暂存）
    this.maxQueueSize = 100;
    this.onMessageCallback = null; // 消息回调
    this.onConnectCallback = null; // 连接回调
    this.onDisconnectCallback = null; // 断开回调
    this.onErrorCallback = null; // 错误回调
    this.reconnectCount = 0;
    this.maxReconnectCount = 10;
  }
  
  /**
   * 初始化
   */
  async init(userId) {
    this.userId = userId;
    
    if (DEBUG_WS) {
      console.log('?? ========== 初始化 tim-presence-manager ==========');
      console.log('?? 用户ID:', userId);
      console.log('?? WebSocket URL:', this.wsUrl);
    }
    
    // 连接 WebSocket（接收服务端推送的状态变更）
    if (DEBUG_WS) console.log('?? 开始连接 WebSocket...');
    this.connectWebSocket();
    
    console.log('✅ tim-presence-manager 初始化完成(WebSocket连接中...)');
    console.log('================================================');
  }
  
  /**
   * 建立 WebSocket 连接
   */
  connectWebSocket() {
    try {
      const wsUrl = `${this.wsUrl}?userId=${this.userId}`;
      if (DEBUG_WS) {
        console.log('?? 准备连接 WebSocket:', wsUrl);
        console.log('   当前用户ID:', this.userId);
        console.log('   WebSocket URL:', wsUrl);
      }
      
      // 先关闭旧连接
      if (this.ws) {
        try {
          uni.closeSocket();
        } catch (e) {
          console.warn('关闭旧连接失败:', e);
        }
      }
      
      this.ws = uni.connectSocket({
        url: wsUrl,
        success: () => {
          if (DEBUG_WS) console.log('✅ WebSocket连接请求已发送成功');
        },
        fail: (err) => {
          console.error('❌ WebSocket连接请求发送失败:', err);
          console.error('   错误详情:', JSON.stringify(err));
          this.scheduleReconnect();
        }
      });
      
      // 使用 SocketTask 对象的监听器(推荐方式)
      this.ws.onOpen((res) => {
        if (DEBUG_WS) {
          console.log('?? ========== WebSocket 连接成功 ==========');
          console.log('   响应数据:', res);
          console.log('   用户ID:', this.userId);
          console.log('   连接URL:', wsUrl);
          console.log('==========================================');
        }
        
        this.isConnected = true;
        this.reconnectCount = 0; // 重置重连计数
        
        // 启动心跳
        this.startHeartbeat();
        
        // 发送队列中的消息
        this.flushMessageQueue();
        
        // 连接成功后，立即上报当前 TIM 连接状态
        this.reportCurrentTIMStatus();
        
        // 触发连接回调
        if (this.onConnectCallback) {
          this.onConnectCallback();
        }
      });
      
      // 监听消息
      this.ws.onMessage((res) => {
        if (DEBUG_WS) console.log('?? 收到WebSocket消息:', res.data);
        this.handleMessage(res.data);
      });
      
      // 监听错误
      this.ws.onError((err) => {
        console.error('❌ ========== WebSocket 错误 ==========');
        console.error('   错误信息:', err);
        console.error('   错误详情:', JSON.stringify(err));
        console.error('   用户ID:', this.userId);
        console.error('   连接URL:', wsUrl);
        console.error('======================================');
        
        this.isConnected = false;
        
        // 触发错误回调
        if (this.onErrorCallback) {
          this.onErrorCallback(err);
        }
        
        this.scheduleReconnect();
      });
      
      // 监听关闭
      this.ws.onClose((res) => {
        if (DEBUG_WS) {
          console.log('?? ========== WebSocket 连接关闭 ==========');
          console.log('   关闭信息:', res);
          console.log('   关闭码:', res?.code);
          console.log('   关闭原因:', res?.reason);
          console.log('   用户ID:', this.userId);
          console.log('=========================================');
        }
        
        this.isConnected = false;
        this.stopHeartbeat();
        
        // 触发断开回调
        if (this.onDisconnectCallback) {
          this.onDisconnectCallback();
        }
        
        this.scheduleReconnect();
      });
      
    } catch (error) {
      console.error('❌ WebSocket连接异常:', error);
      this.scheduleReconnect();
    }
  }
  
  /**
   * 监听 TIM 连接状态变更
   */
  listenTIMConnectionStatus() {
    if (!timManager.tim || !timManager.tim.TIM) {
      console.warn('⚠️ TIM 未初始化或 TIM 对象不完整，无法监听连接状态');
      return;
    }
    
    const TIM = timManager.tim.TIM;
    
    // 监听 IM 连接状态变化
    this.timConnectListener = (event) => {
      if (DEBUG_WS) console.log('?? TIM 连接状态变更:', event.data.state);
      
      let imStatus = 'offline';
      
      // 映射 TIM 状态到业务状态
      switch (event.data.state) {
        case TIM.TYPES.NET_STATE_CONNECTED:
          imStatus = 'online';
          break;
        case TIM.TYPES.NET_STATE_DISCONNECTED:
        case TIM.TYPES.NET_STATE_CONNECTING:
          imStatus = 'offline';
          break;
      }
      
      // 通过 WebSocket 上报状态给服务端
      this.reportIMStatus(imStatus);
    };
    
    timManager.tim.on(TIM.EVENT.NET_STATE_CHANGE, this.timConnectListener);
    if (DEBUG_WS) console.log('✅ 已监听 TIM 连接状态变更');
  }
  
  /**
   * 监听 TIM 用户状态更新（好友状态）
   */
  listenTIMUserStatus() {
    if (!timManager.tim || !timManager.tim.TIM) {
      console.warn('⚠️ TIM 未初始化或 TIM 对象不完整，无法监听用户状态');
      return;
    }
    
    const TIM = timManager.tim.TIM;
    
    // 监听用户状态更新事件
    this.timStatusListener = (event) => {
      console.log('=== ?? 收到 TIM 用户状态更新事件 ===');
      console.log('   - 事件数据:', JSON.stringify(event.data, null, 2));
      
      const { userStatusList } = event.data;
      
      if (userStatusList && userStatusList.length > 0) {
        console.log(`   - 状态变更用户数: ${userStatusList.length}`);
        
        userStatusList.forEach(item => {
          const userId = item.userID;
          console.log(`   - 用户 ${userId}:`);
          console.log(`     原始状态类型: ${item.statusType}`);
          console.log(`     USER_STATUS_ONLINE: ${TIM.TYPES.USER_STATUS_ONLINE}`);
          console.log(`     USER_STATUS_OFFLINE: ${TIM.TYPES.USER_STATUS_OFFLINE}`);
          
          const status = item.statusType === TIM.TYPES.USER_STATUS_ONLINE ? 'online' : 'offline';
          console.log(`     判断结果: ${status}`);
          
          // 更新本地缓存
          this.onlineStatusCache.set(String(userId), status === 'online');
          console.log(`     已更新缓存: ${status === 'online'}`);
          
          // 通知状态变化
          this.notifyStatusChange(String(userId), status);
          
          // 也可以通过 WS 上报给服务端，保证服务端状态一致
          this.reportFriendStatus(userId, status);
        });
      } else {
        console.warn('   ⚠️ userStatusList 为空或不存在');
      }
      console.log('=== 状态更新处理完成 ===');
    };
    
    timManager.tim.on(TIM.EVENT.USER_STATUS_UPDATED, this.timStatusListener);
    console.log('✅ 已监听 TIM 用户状态更新事件');
    console.log('   - 事件名称:', TIM.EVENT.USER_STATUS_UPDATED);
  }
  
  /**
   * 上报当前 TIM 连接状态
   */
  reportCurrentTIMStatus() {
    if (!timManager.isLogin) {
      this.reportIMStatus('offline');
      return;
    }
    
    // TIM 已登录，上报在线状态
    this.reportIMStatus('online');
  }
  
  /**
   * 上报 IM 状态给服务端
   * @param {String} status 状态：online/offline
   */
  reportIMStatus(status) {
    if (!this.isConnected) {
      console.warn('⚠️ WebSocket 未连接，无法上报 IM 状态');
      return;
    }
    
    this.sendMessage({
      type: 'imStatusReport',
      userId: this.userId,
      status: status,
      device: 'mobile', // 设备类型
      timestamp: Date.now()
    });
    
    console.log(`?? 已上报 IM 状态: ${status}`);
  }
  
  /**
   * 上报好友状态给服务端
   * @param {String} friendUserId 好友用户ID
   * @param {String} status 状态：online/offline
   */
  reportFriendStatus(friendUserId, status) {
    if (!this.isConnected) {
      return;
    }
    
    this.sendMessage({
      type: 'friendStatusReport',
      userId: friendUserId,
      status: status,
      timestamp: Date.now()
    });
  }
  
  /**
   * 订阅用户状态（使用 TIM 原生能力）
   * @param {Array<String>} userIdList 用户ID列表
   */
  async subscribeUserStatus(userIdList) {
    if (!timManager.tim || !timManager.isLogin) {
      console.warn('⚠️ TIM 未登录，无法订阅用户状态');
      console.warn('   - timManager.tim:', !!timManager.tim);
      console.warn('   - timManager.isLogin:', timManager.isLogin);
      
      // 使用 HTTP 轮询作为备用方案
      console.log('?? 启用 HTTP 轮询备用方案');
      this.startHttpPolling(userIdList);
      return;
    }
    
    console.log('?? 开始订阅用户状态...');
    console.log('   - 订阅用户列表:', userIdList);
    console.log('   - TIM SDK 版本:', timManager.tim.VERSION);
    
    try {
      const result = await timManager.tim.subscribeUserStatus({
        userIDList: userIdList.map(id => String(id))
      });
      
      console.log('✅ 订阅用户状态成功!');
      console.log('   - 完整结果:', JSON.stringify(result, null, 2));
      
      // 订阅成功后，初始化这些用户的状态
      if (result.data && result.data.successUserList) {
        console.log('?? 成功订阅的用户列表:', result.data.successUserList.length, '个');
        
        result.data.successUserList.forEach(user => {
          console.log(`   - 用户 ${user.userID}:`);
          console.log(`     状态类型: ${user.statusType}`);
          console.log(`     USER_STATUS_ONLINE 常量:`, timManager.tim.TIM.TYPES.USER_STATUS_ONLINE);
          console.log(`     USER_STATUS_OFFLINE 常量:`, timManager.tim.TIM.TYPES.USER_STATUS_OFFLINE);
          
          const status = user.statusType === timManager.tim.TIM.TYPES.USER_STATUS_ONLINE ? 'online' : 'offline';
          console.log(`     最终判断状态: ${status}`);
          
          this.onlineStatusCache.set(String(user.userID), status === 'online');
          this.notifyStatusChange(String(user.userID), status);
        });
      }
      
      // 检查失败列表
      if (result.data && result.data.failureUserList && result.data.failureUserList.length > 0) {
        console.warn('⚠️ 部分用户订阅失败:', result.data.failureUserList);
      }
      
      return result;
    } catch (error) {
      console.error('❌ 订阅用户状态失败:', error);
      console.error('   - 错误详情:', error.message);
      console.error('   - 错误代码:', error.code);
      
      // 如果订阅失败，启用 HTTP 轮询备用方案
      if (error.code === 70402 || error.code === 70403) {
        console.log('?? TIM 在线状态功能未开启，启用 HTTP 轮询备用方案');
        this.startHttpPolling(userIdList);
      }
      
      throw error;
    }
  }
  
  /**
   * HTTP 轮询备用方案（当 TIM 订阅失败时使用）
   * @param {Array<String>} userIdList 用户ID列表
   */
  startHttpPolling(userIdList) {
    console.log('?? 启动 HTTP 轮询，间隔 30 秒');
    
    // 立即查询一次
    this.pollUserStatus(userIdList);
    
    // 每 30 秒轮询一次
    this.pollingTimer = setInterval(() => {
      this.pollUserStatus(userIdList);
    }, 30000);
  }
  
  /**
   * 轮询用户状态
   */
  async pollUserStatus(userIdList) {
    for (const userId of userIdList) {
      try {
        const [err, res] = await uni.request({
          url: 'http://localhost:8083/api/online/checkStatus',
          method: 'GET',
          data: { userId }
        });
        
        if (!err && res.data && res.data.code === 200) {
          const isOnline = res.data.data.online || false;
          const oldStatus = this.onlineStatusCache.get(String(userId));
          
          // 只有状态变化时才通知
          if (oldStatus !== isOnline) {
            this.onlineStatusCache.set(String(userId), isOnline);
            this.notifyStatusChange(String(userId), isOnline ? 'online' : 'offline');
          }
        }
      } catch (error) {
        console.error(`查询用户 ${userId} 状态失败:`, error);
      }
    }
  }
  
  /**
   * 停止 HTTP 轮询
   */
  stopHttpPolling() {
    if (this.pollingTimer) {
      clearInterval(this.pollingTimer);
      this.pollingTimer = null;
      console.log('?? 已停止 HTTP 轮询');
    }
  }
  
  /**
   * 取消订阅用户状态
   * @param {Array<String>} userIdList 用户ID列表
   */
  async unsubscribeUserStatus(userIdList) {
    if (!timManager.tim || !timManager.isLogin) {
      return;
    }
    
    try {
      await timManager.tim.unsubscribeUserStatus({
        userIDList: userIdList.map(id => String(id))
      });
      console.log('✅ 取消订阅用户状态成功');
    } catch (error) {
      console.error('❌ 取消订阅用户状态失败:', error);
    }
  }
  
  /**
   * 处理接收到的消息
   */
  handleMessage(data) {
    try {
      const message = typeof data === 'string' ? JSON.parse(data) : data;
      
      switch (message.type) {
        case 'pong':  // 改为小写,匹配后端
          // 心跳响应
          console.log('?? 收到心跳响应');
          break;
          
        case 'ONLINE':
        case 'STATUS_UPDATE':
          // 用户上线/状态更新通知
          if (message.userId || message.fromUserId) {
            const userId = String(message.userId || message.fromUserId);
            const isOnline = message.online !== undefined ? message.online : (message.type === 'ONLINE');
            
            this.onlineStatusCache.set(userId, isOnline);
            this.notifyStatusChange(userId, isOnline ? 'online' : 'offline');
          }
          break;
          
        case 'OFFLINE':
          // 用户离线通知
          if (message.userId || message.fromUserId) {
            const userId = String(message.userId || message.fromUserId);
            this.onlineStatusCache.set(userId, false);
            this.notifyStatusChange(userId, 'offline');
          }
          break;
      }
    } catch (error) {
      console.error('❌ 消息解析失败:', error);
    }
  }
  
  /**
   * 启动心跳
   */
  startHeartbeat() {
    this.stopHeartbeat();
    
    this.heartbeatTimer = setInterval(() => {
      if (this.isConnected) {
        console.log('?? ========== 发送心跳PING ==========');
        console.log('?? 用户ID:', this.userId);
        console.log('?? WebSocket连接状态:', this.isConnected);
        console.log('?? 发送消息:', {
          type: 'ping',
          fromUserId: this.userId,
          timestamp: Date.now()
        });
        
        this.sendMessage({
          type: 'ping',  // 改为小写,匹配后端
          fromUserId: this.userId,
          timestamp: Date.now()
        });
        
        console.log('?? ====================================');
      } else {
        console.warn('⚠️ WebSocket未连接,跳过心跳');
      }
    }, this.heartbeatInterval);
  }
  
  /**
   * 停止心跳
   */
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
  }
  
  /**
   * 发送消息
   */
  sendMessage(data) {
    if (!this.isConnected) {
      console.warn('⚠️ WebSocket未连接，无法发送消息');
      return;
    }
    
    try {
      uni.sendSocketMessage({
        data: JSON.stringify(data),
        fail: (err) => {
          console.error('❌ 发送消息失败:', err);
        }
      });
    } catch (error) {
      console.error('❌ 发送消息异常:', error);
    }
  }
  
  /**
   * 监听用户状态变化
   * @param {String} targetUserId 目标用户ID
   * @param {Function} callback 回调函数 (status) => {}
   */
  onStatusChange(targetUserId, callback) {
    if (!this.statusCallbacks.has(targetUserId)) {
      this.statusCallbacks.set(targetUserId, []);
    }
    this.statusCallbacks.get(targetUserId).push(callback);
  }
  
  /**
   * 移除状态监听
   * @param {String} targetUserId 目标用户ID
   * @param {Function} callback 回调函数
   */
  offStatusChange(targetUserId, callback) {
    if (!this.statusCallbacks.has(targetUserId)) {
      return;
    }
    
    const callbacks = this.statusCallbacks.get(targetUserId);
    const index = callbacks.indexOf(callback);
    if (index > -1) {
      callbacks.splice(index, 1);
    }
    
    if (callbacks.length === 0) {
      this.statusCallbacks.delete(targetUserId);
    }
  }
  
  /**
   * 通知状态变化
   */
  notifyStatusChange(userId, status) {
    console.log(`?? 用户 ${userId} 状态变更: ${status}`);
    
    const callbacks = this.statusCallbacks.get(userId);
    if (callbacks && callbacks.length > 0) {
      callbacks.forEach(callback => {
        try {
          callback(status);
        } catch (error) {
          console.error('❌ 状态回调执行失败:', error);
        }
      });
    }
  }
  
  /**
   * 获取缓存的在线状态
   * @param {String} userId 目标用户ID
   * @return {Boolean|null} 在线状态，null表示未知
   */
  getCachedStatus(userId) {
    return this.onlineStatusCache.get(String(userId)) || null;
  }
  
  /**
   * 计划重连
   */
  scheduleReconnect() {
    if (this.reconnectTimer) {
      return;
    }
    
    console.log('?? 将在5秒后重连...');
    this.reconnectTimer = setTimeout(() => {
      this.reconnectTimer = null;
      if (!this.isConnected && this.userId) {
        console.log('?? 尝试重连...');
        this.connectWebSocket();
      }
    }, this.reconnectInterval);
  }
  
  /**
   * 发送队列中的消息
   */
  flushMessageQueue() {
    if (this.messageQueue.length === 0) {
      return;
    }
    
    console.log(`?? 发送队列中的 ${this.messageQueue.length} 条消息`);
    
    while (this.messageQueue.length > 0) {
      const message = this.messageQueue.shift();
      this.sendMessage(message);
    }
  }
  
  /**
   * 断开连接
   */
  disconnect() {
    this.stopHeartbeat();
    this.stopHttpPolling(); // 停止 HTTP 轮询
    
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
      this.reconnectTimer = null;
    }
    
    // 移除 TIM 事件监听
    if (timManager.tim) {
      const TIM = timManager.tim.TIM;
      if (this.timConnectListener) {
        timManager.tim.off(TIM.EVENT.NET_STATE_CHANGE, this.timConnectListener);
      }
      if (this.timStatusListener) {
        timManager.tim.off(TIM.EVENT.USER_STATUS_UPDATED, this.timStatusListener);
      }
    }
    
    if (this.isConnected) {
      uni.closeSocket();
      this.isConnected = false;
    }
    
    this.statusCallbacks.clear();
    this.userId = null;
  }
  
  /**
   * 获取连接状态
   */
  getConnectionStatus() {
    return this.isConnected;
  }
}

// 导出单例
export default new TIMPresenceManager();
