const config = require('../config/config.js');

/**
 * 微信小程序专用WebSocket管理器 V2
 * 针对小程序环境优化，解决连接问题
 */
class WebSocketManagerV2 {
  constructor() {

    this.ws = null;
    this.isConnected = false;
    this.isConnecting = false;
    this.reconnectAttempts = 0;
    this.maxReconnectAttempts = 8; // 增加重连次数
    this.reconnectInterval = 2000; // 2秒
    this.heartbeatInterval = null;
    this.heartbeatTimeout = 30000; // 30秒心跳
    this.connectionTimeout = null;

    // 认证信息
    this.token = null;
    this.deviceId = null;

    // 事件处理器
    this.messageHandlers = new Map();
    this.eventHandlers = new Map();

    // 消息队列
    this.messageQueue = [];
    this.messageIdCounter = 0;

    // 性能监控
    this.performanceStats = {
      connectionAttempts: 0,
      successfulConnections: 0,
      failedConnections: 0,
      messagesSent: 0,
      messagesReceived: 0,
      reconnectCount: 0,
      lastConnectTime: null,
      lastDisconnectTime: null,
      averageLatency: 0,
      latencyHistory: []
    };

    // 连接质量监控
    this.connectionQuality = {
      score: 100, // 0-100分
      factors: {
        stability: 100,    // 连接稳定性
        latency: 100,      // 延迟
        reliability: 100   // 可靠性
      }
    };

    // 智能重连配置
    this.smartReconnect = {
      enabled: true,
      adaptiveDelay: true,
      maxDelay: 60000, // 最大延迟60秒
      backoffFactor: 1.5,
      jitterRange: 0.1 // 10%的随机抖动
    };

    // 初始化设备ID
    this.initDeviceId();

    // 绑定方法上下文
    this.onOpen = this.onOpen.bind(this);
    this.onMessage = this.onMessage.bind(this);
    this.onError = this.onError.bind(this);
    this.onClose = this.onClose.bind(this);
  }

  // 初始化设备ID
  initDeviceId() {
    try {
      let deviceId = wx.getStorageSync('device_id');
      if (!deviceId) {
        deviceId = 'mp_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
        wx.setStorageSync('device_id', deviceId);

      } else {

      }
      this.deviceId = deviceId;

    } catch (error) {
      console.error('❌ 设备ID初始化失败:', error);
      this.deviceId = 'mp_unknown_' + Date.now();
    }
  }

  // 设置认证token
  setToken(token) {
    this.token = token;

  }

  // 获取认证token
  getToken() {
    if (this.token) {
      return this.token;
    }

    try {
      // 方式1：从app.globalData获取
      const app = getApp();
      if (app?.globalData?.userInfo?.token) {
        this.token = app.globalData.userInfo.token;

        return this.token;
      }

      // 方式2：从本地存储获取userInfo
      const userInfo = wx.getStorageSync('userInfo');
      if (userInfo?.token) {
        this.token = userInfo.token;

        return this.token;
      }

      // 方式3：直接从本地存储获取token
      const directToken = wx.getStorageSync('token');
      if (directToken) {
        this.token = directToken;

        return this.token;
      }

      console.warn('⚠️ 未找到有效的token');
      return null;
    } catch (error) {
      console.error('❌ 获取token失败:', error);
      return null;
    }
  }

  // 连接WebSocket
  async connect() {    if (this.ws) {

      // 0: CONNECTING, 1: OPEN, 2: CLOSING, 3: CLOSED
    }

    if (this.isConnected) {

      return Promise.resolve();
    }

    if (this.isConnecting) {

      return this.waitForConnection();
    }

    return new Promise((resolve, reject) => {

      this.isConnecting = true;

      // 记录连接尝试
      this.performanceStats.connectionAttempts++;
      const connectStartTime = Date.now();

      // 获取token
      const token = this.getToken();
      if (!token) {
        console.error('❌ 缺少认证token，无法连接WebSocket');
        this.isConnecting = false;
        this.performanceStats.failedConnections++;
        reject(new Error('缺少认证token'));
        return;
      }

      // 构建WebSocket URL
      const wsUrl = config.websocket?.url || 'wss://api.faxianwo.me/api/v1/ws';
      const fullUrl = `${wsUrl}?device_id=${encodeURIComponent(this.deviceId)}`;

      try {
        // 小程序WebSocket连接配置
        const connectOptions = {
          url: fullUrl,
          header: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
          },
          timeout: 15000
        };

        this.ws = wx.connectSocket(connectOptions);

        // 设置连接超时
        this.connectionTimeout = setTimeout(() => {
          if (this.isConnecting && !this.isConnected) {
            console.error('❌ WebSocket连接超时');
            this.cleanup();
            reject(new Error('连接超时'));
          }
        }, 20000);

        // 事件监听
        this.ws.onOpen((res) => {
          const connectTime = Date.now() - connectStartTime;
          console.log(`🎉 WebSocket连接成功 (${connectTime}ms)`);

          // 更新性能统计
          this.performanceStats.successfulConnections++;
          this.performanceStats.lastConnectTime = Date.now();
          this.updateConnectionQuality('connect_success', connectTime);

          this.onOpen(res);
          resolve();
        });

        this.ws.onMessage((res) => {
          this.performanceStats.messagesReceived++;
          console.log('🔥 WebSocket原始接收:', {
            data: res.data,
            dataType: typeof res.data,
            dataLength: res.data ? res.data.length : 0,
            timestamp: new Date().toLocaleTimeString()
          });
          try {
            this.onMessage(res);
          } catch (error) {
            console.error('🔥 this.onMessage调用失败:', error);
          }
        });

        this.ws.onError((error) => {
          console.error('💥 WebSocket连接错误:', error);
          this.performanceStats.failedConnections++;
          this.updateConnectionQuality('connect_error');

          this.onError(error);
          if (this.isConnecting) {
            reject(error);
          }
        });

        this.ws.onClose((res) => {

          this.performanceStats.lastDisconnectTime = Date.now();
          this.updateConnectionQuality('disconnect', res.code);

          this.onClose(res);
          if (this.isConnecting) {
            reject(new Error('连接被关闭'));
          }
        });

      } catch (error) {
        console.error('❌ WebSocket连接创建失败:', error);
        this.cleanup();

        // 检查域名配置问题
        if (error.errMsg?.includes('url not in domain list')) {
          console.error('💡 请在微信公众平台配置WebSocket域名: wss://api.faxianwo.me');
        }

        reject(error);
      }
    });
  }

  // 等待连接完成
  waitForConnection() {
    return new Promise((resolve, reject) => {
      const checkConnection = () => {
        if (this.isConnected) {
          resolve();
        } else if (!this.isConnecting) {
          reject(new Error('连接失败'));
        } else {
          setTimeout(checkConnection, 100);
        }
      };
      checkConnection();
    });
  }

  // 清理连接状态
  cleanup() {
    this.isConnecting = false;
    if (this.connectionTimeout) {
      clearTimeout(this.connectionTimeout);
      this.connectionTimeout = null;
    }
  }

  // 连接成功处理
  onOpen(res) {

    console.log('📊 连接详情:', {
      deviceId: this.deviceId,
      hasToken: !!this.token,
      reconnectAttempts: this.reconnectAttempts,
      timestamp: new Date().toLocaleTimeString()
    });

    this.isConnected = true;
    this.isConnecting = false;
    this.reconnectAttempts = 0;

    this.cleanup();
    this.startHeartbeat();
    this.processMessageQueue();
    this.triggerEvent('connected', res);
  }

  // 消息处理
  onMessage(event) {
    try {
      const message = JSON.parse(event.data);
      console.log('📨 WebSocket收到原始消息:', {
        type: message.type || 'unknown',
        hasData: !!message.data,
        messageKeys: Object.keys(message),
        deviceId: this.deviceId,
        timestamp: new Date().toLocaleTimeString()
      });

      // 心跳响应
      if (message.type === 'pong' || message.type === 'heartbeat_response') {

        return;
      }

      // 🔥 根据消息类型分发到对应的事件处理器
      switch (message.type) {
        case 'new_message':

          this.triggerEvent('new_message', message);

          break;
        case 'message_status':
          this.triggerEvent('message_status', message);
          break;
        case 'message_sent':
          // 标准响应：消息发送成功（包括撤回成功）
          this.triggerEvent('message_sent', message);
          break;
        case 'message_recalled':
          // 收到其他用户撤回消息的通知
          this.triggerEvent('message_recalled', message);
          break;
        case 'error':
          // 错误响应（包括撤回失败）
          this.triggerEvent('error', message);
          break;
        case 'unread_count_update':
          this.triggerEvent('unread_count_update', message);
          break;
        // 🔥 在线状态相关（presence）
        case 'user_online':
          this.triggerEvent('user_online', message);
          this.triggerEvent('message', message); // 兼容通用监听
          break;
        case 'user_offline':
          this.triggerEvent('user_offline', message);
          this.triggerEvent('message', message); // 兼容通用监听
          break;
        case 'presence_update':
          this.triggerEvent('presence_update', message);
          this.triggerEvent('message', message); // 兼容通用监听
          break;
        case 'friend_request':
          this.triggerEvent('friend_request', message);
          break;
        case 'notification':
          this.triggerEvent('notification', message);
          break;
        case 'chat_message':
          this.triggerEvent('chat_message', message);
          break;
        default:
          // 尝试查找特定类型的处理器
          const handler = this.messageHandlers.get(message.type);
          if (handler) {
            handler(message);
          } else {
            // 触发通用消息事件
            this.triggerEvent('message', message);
          }
      }

    } catch (error) {
      console.error('❌ 消息解析失败:', error);
    }
  }

  // 错误处理
  onError(error) {
    console.error('❌ WebSocket错误:', error);
    this.isConnected = false;
    this.cleanup();
    this.triggerEvent('error', error);
    this.scheduleReconnect();
  }

  // 连接关闭处理
  onClose(event) {

    this.isConnected = false;
    this.cleanup();
    this.stopHeartbeat();
    this.triggerEvent('disconnected', event);

    // 非正常关闭时重连
    if (event.code !== 1000) {
      this.scheduleReconnect();
    }
  }

  // 发送消息（带性能监控）
  send(message) {
    if (!this.isConnected) {
      console.warn('⚠️ WebSocket未连接，消息加入队列');
      this.messageQueue.push(message);
      this.connect().catch(console.error);
      return false;
    }

    try {
      const messageStr = typeof message === 'string' ? message : JSON.stringify(message);
      const sendTime = Date.now();

      this.ws.send({
        data: messageStr,
        success: () => {
          this.performanceStats.messagesSent++;

          // 如果是心跳消息，记录延迟
          if (message.type === 'heartbeat') {
            this.recordLatency(sendTime);
          }
        },
        fail: (error) => {
          console.error('❌ 消息发送失败:', error);
          this.updateConnectionQuality('send_error');
        }
      });
      return true;
    } catch (error) {
      console.error('❌ 消息发送失败:', error);
      this.updateConnectionQuality('send_exception');
      return false;
    }
  }

  // 处理消息队列
  processMessageQueue() {
    while (this.messageQueue.length > 0 && this.isConnected) {
      const message = this.messageQueue.shift();
      this.send(message);
    }
  }

  // 开始心跳 - 使用WebSocket原生ping/pong
  startHeartbeat() {
    this.stopHeartbeat();
    this.heartbeatInterval = setInterval(() => {

      console.log("发送心跳---->");
      if (this.isConnected && this.ws) {
        try {
          // 使用微信小程序的ping方法（如果支持）
          if (typeof this.ws.ping === 'function') {
            this.ws.ping();

          } else {
            // 降级：发送应用层心跳（使用正确的格式）
            const heartbeatMessage = {
              type: 'heartbeat',
              id: `heartbeat_${Date.now()}`,
              data: {
                timestamp: Date.now()
              }
            };
            this.send(heartbeatMessage);

          }
        } catch (error) {
          console.error('❌ 心跳发送失败:', error);
        }
      }
    }, this.heartbeatTimeout);
  }

  // 停止心跳
  stopHeartbeat() {
    if (this.heartbeatInterval) {
      clearInterval(this.heartbeatInterval);
      this.heartbeatInterval = null;
    }
  }

  // 智能重连机制
  scheduleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.error('❌ 达到最大重连次数，停止重连');
      this.triggerEvent('max_reconnect_reached');
      return;
    }

    // 智能延迟计算
    let delay;
    if (this.smartReconnect.adaptiveDelay) {
      // 基于连接质量调整延迟
      const qualityFactor = this.connectionQuality.score / 100;
      const baseDelay = this.reconnectInterval * Math.pow(this.smartReconnect.backoffFactor, this.reconnectAttempts);
      delay = Math.min(baseDelay / qualityFactor, this.smartReconnect.maxDelay);

      // 添加随机抖动，避免雷群效应
      const jitter = delay * this.smartReconnect.jitterRange * (Math.random() - 0.5);
      delay = Math.max(1000, delay + jitter); // 最小1秒
    } else {
      delay = this.reconnectInterval * Math.pow(2, this.reconnectAttempts);
    }

    console.log(`🔄 ${Math.round(delay)}ms后尝试第${this.reconnectAttempts + 1}次重连 (质量分数: ${this.connectionQuality.score})`);

    // 更新统计
    this.performanceStats.reconnectCount++;

    setTimeout(() => {
      this.reconnectAttempts++;
      this.connect().catch((error) => {
        console.error('重连失败:', error);
        this.scheduleReconnect(); // 继续重连
      });
    }, delay);
  }

  // 断开连接
  disconnect() {

    this.stopHeartbeat();
    this.cleanup();

    if (this.ws) {
      this.ws.close();
      this.ws = null;
    }

    this.isConnected = false;
    this.reconnectAttempts = this.maxReconnectAttempts; // 阻止重连
  }

  // 注册消息处理器
  registerMessageHandler(type, handler) {
    this.messageHandlers.set(type, handler);
  }

  // 发送聊天消息 - 符合API文档规范
  sendChatMessage(receiverId, content, msgType = 0, chatType = 0, options = {}) {
    // 生成客户端消息ID
    const clientMsgId = this.generateMessageId();

    // 🔥 消息类型映射 - 修正为与API文档一致
    const msgTypeMap = {
      'text': 0,      // 文字消息
      'image': 1,     // 图片消息
      'voice': 2,     // 语音消息
      'video': 3,     // 视频消息
      'file': 4,      // 文件消息
      'emoji': 6,     // 表情消息
      'location': 5   // 位置消息
    };

    // 🔥 详细记录消息类型转换过程

    // 如果msgType是字符串，转换为数字
    if (typeof msgType === 'string') {
      const convertedMsgType = msgTypeMap[msgType] || 0;

      msgType = convertedMsgType;
    }

    const message = {
      type: 'send_message',
      id: clientMsgId,
      data: {
        receiverId: receiverId,
        chatType: chatType,
        msgType: msgType,
        content: content,
        atUsers: options.atUsers || [],
        replyTo: options.replyTo || '',
        extra: options.extra || ''
      }
    };

    console.log('📤 发送聊天消息:', {
      type: 'send_message',
      id: clientMsgId,
      receiverId,
      chatType,
      msgType,
      contentLength: content ? content.length : 0,
      contentPreview: content ? (content.substring(0, 50) + (content.length > 50 ? '...' : '')) : 'null'
    });

    return this.send(message);
  }

  // 生成消息ID
  generateMessageId() {
    this.messageIdCounter++;
    return `client_msg_${Date.now()}_${this.messageIdCounter}`;
  }

  // 发送图片消息
  sendImageMessage(receiverId, imageUrl, chatType = 0, options = {}) {
    return this.sendChatMessage(receiverId, imageUrl, 1, chatType, options);
  }

  // 发送语音消息
  sendVoiceMessage(receiverId, voiceUrl, duration, chatType = 0, options = {}) {
    const content = JSON.stringify({
      url: voiceUrl,
      duration: duration
    });
    return this.sendChatMessage(receiverId, content, 2, chatType, options);
  }

  // 发送视频消息
  sendVideoMessage(receiverId, videoUrl, duration, thumbnail, chatType = 0, options = {}) {
    const content = JSON.stringify({
      url: videoUrl,
      duration: duration,
      thumbnail: thumbnail
    });
    return this.sendChatMessage(receiverId, content, 3, chatType, options);
  }

  // 发送位置消息
  sendLocationMessage(receiverId, latitude, longitude, address, locationName, chatType = 0, options = {}) {
    const message = {
      type: 'send_location',
      id: this.generateMessageId(),
      data: {
        receiverId: receiverId,
        chatType: chatType,
        latitude: latitude,
        longitude: longitude,
        address: address,
        locationName: locationName
      }
    };

    return this.send(message);
  }

  // 撤回消息
  recallMessage(messageId) {
    const message = {
      type: 'recall_message',
      id: this.generateMessageId(),
      data: {
        messageId: messageId
      }
    };

    return this.send(message);
  }

  // 标记消息已读
  markMessageRead(messageIds) {
    const message = {
      type: 'mark_read',
      id: this.generateMessageId(),
      data: {
        messageIds: Array.isArray(messageIds) ? messageIds : [messageIds]
      }
    };

    return this.send(message);
  }

  // 注册事件处理器
  on(event, handler) {
    if (!this.eventHandlers.has(event)) {
      this.eventHandlers.set(event, []);
    }
    this.eventHandlers.get(event).push(handler);
  }

  // 移除事件处理器
  off(event, handler) {
    if (!this.eventHandlers.has(event)) {
      return;
    }

    const handlers = this.eventHandlers.get(event);
    if (handler) {
      // 移除特定的处理器
      const index = handlers.indexOf(handler);
      if (index > -1) {
        handlers.splice(index, 1);
      }
    } else {
      // 移除所有处理器
      this.eventHandlers.set(event, []);
    }

    // 如果没有处理器了，删除整个事件
    if (handlers.length === 0) {
      this.eventHandlers.delete(event);
    }
  }

  // 触发事件
  triggerEvent(event, data) {
    const handlers = this.eventHandlers.get(event);
    const handlerCount = Array.isArray(handlers) ? handlers.length : 0;

    if (handlerCount > 0) {

      handlers.forEach((handler, index) => {
        try {

          handler(data);

        } catch (error) {
          console.error(`❌ 事件处理器错误 [${event}]:`, error);
        }
      });
    } else {

    }
  }

  // 获取连接状态
  getStatus() {
    return {
      isConnected: this.isConnected,
      isConnecting: this.isConnecting,
      reconnectAttempts: this.reconnectAttempts,
      hasToken: !!this.token,
      deviceId: this.deviceId
    };
  }

  // 兼容性方法 - 为了向后兼容
  getConnectionStatus() {
    return {
      connected: this.isConnected,
      connecting: this.isConnecting
    };
  }

  // ===== 聊天功能相关方法 =====

  // 发送输入状态
  sendTypingStatus(conversationId, isTyping) {
    try {
      if (!this.isConnected) {
        console.warn('⚠️ WebSocket未连接，无法发送输入状态');
        return false;
      }

      const message = {
        type: 'typing_status',
        id: `typing_${Date.now()}`,
        data: {
          conversationId: conversationId,
          isTyping: isTyping,
          timestamp: Date.now()
        }
      };

      console.log('📝 发送输入状态:', {
        conversationId,
        isTyping,
        timestamp: Date.now()
      });

      return this.send(message);
    } catch (error) {
      console.error('❌ 发送输入状态失败:', error);
      return false;
    }
  }

  // 发送已读回执
  sendReadReceipt(messageId) {
    try {
      if (!this.isConnected) {
        console.warn('⚠️ WebSocket未连接，无法发送已读回执');
        return false;
      }

      const message = {
        type: 'mark_read',
        id: `read_${Date.now()}`,
        data: {
          messageId: messageId,
          timestamp: Date.now()
        }
      };

      console.log('✅ 发送已读回执:', {
        messageId,
        timestamp: Date.now()
      });

      return this.send(message);
    } catch (error) {
      console.error('❌ 发送已读回执失败:', error);
      return false;
    }
  }

  // 聊天消息处理器注册
  onChatMessage(handler) {
    this.on('new_message', handler);
    this.on('chat_message', handler);
  }

  // 未读数更新处理器注册
  onUnreadCountUpdate(handler) {
    this.on('unread_count_update', handler);
    this.on('unread_update', handler);
  }

  // 通知处理器注册
  onNotification(handler) {
    this.on('notification', handler);
  }

  // 好友请求处理器注册
  onFriendRequest(handler) {
    this.on('friend_request', handler);
  }

  // 发送聊天消息（兼容旧版本接口）- 重定向到标准方法
  sendChatMessageLegacy(targetId, content, messageType = 'text', extra = {}) {
    // 转换消息类型
    const msgTypeMap = {
      'text': 1,
      'image': 2,
      'voice': 3,
      'video': 4,
      'file': 5,
      'emoji': 6,
      'location': 7
    };

    const msgType = msgTypeMap[messageType] || 1;
    const chatType = extra.chatType || 0;

    return this.sendChatMessage(targetId, content, msgType, chatType, extra);
  }

  // 生成消息ID
  generateMessageId() {
    return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  // ===== 性能监控方法 =====

  // 记录延迟
  recordLatency(sendTime) {
    const latency = Date.now() - sendTime;
    this.performanceStats.latencyHistory.push(latency);

    // 只保留最近50次的延迟记录
    if (this.performanceStats.latencyHistory.length > 50) {
      this.performanceStats.latencyHistory.shift();
    }

    // 计算平均延迟
    const sum = this.performanceStats.latencyHistory.reduce((a, b) => a + b, 0);
    this.performanceStats.averageLatency = sum / this.performanceStats.latencyHistory.length;

    // 更新连接质量
    this.updateConnectionQuality('latency', latency);
  }

  // 更新连接质量评分
  updateConnectionQuality(event, value = null) {
    const factors = this.connectionQuality.factors;

    switch (event) {
      case 'connect_success':
        factors.reliability = Math.min(100, factors.reliability + 5);
        if (value < 3000) factors.latency = Math.min(100, factors.latency + 2);
        break;

      case 'connect_error':
        factors.reliability = Math.max(0, factors.reliability - 10);
        factors.stability = Math.max(0, factors.stability - 5);
        break;

      case 'disconnect':
        if (value !== 1000) { // 非正常关闭
          factors.stability = Math.max(0, factors.stability - 8);
        }
        break;

      case 'send_error':
      case 'send_exception':
        factors.reliability = Math.max(0, factors.reliability - 3);
        break;

      case 'latency':
        if (value > 5000) {
          factors.latency = Math.max(0, factors.latency - 5);
        } else if (value < 1000) {
          factors.latency = Math.min(100, factors.latency + 1);
        }
        break;
    }

    // 计算总分
    this.connectionQuality.score = Math.round(
      (factors.stability + factors.latency + factors.reliability) / 3
    );

  }

  // 获取性能统计
  getPerformanceStats() {
    return {
      ...this.performanceStats,
      connectionQuality: this.connectionQuality,
      uptime: this.performanceStats.lastConnectTime ?
        Date.now() - this.performanceStats.lastConnectTime : 0
    };
  }

  // 重置性能统计
  resetPerformanceStats() {
    this.performanceStats = {
      connectionAttempts: 0,
      successfulConnections: 0,
      failedConnections: 0,
      messagesSent: 0,
      messagesReceived: 0,
      reconnectCount: 0,
      lastConnectTime: null,
      lastDisconnectTime: null,
      averageLatency: 0,
      latencyHistory: []
    };

    this.connectionQuality = {
      score: 100,
      factors: {
        stability: 100,
        latency: 100,
        reliability: 100
      }
    };
  }

  // ===== 兼容性别名方法 =====

  // 兼容旧版本的 sendMessage 方法
  sendMessage(message) {
    return this.send(message);
  }
}

// 创建全局实例
const wsManager = new WebSocketManagerV2();

module.exports = wsManager;

