/**
 * WebSocket管理器
 * 负责WebSocket连接、消息收发、重连、心跳等功能
 */
import { websocketConfig } from '@/config/websocket.js';

export class WebSocketManager {
  constructor(url = null) {
    // 使用配置文件中的URL，如果传入了url则使用传入的
    this.url = url || websocketConfig.getUrl();
    this.socket = null;
    this.isConnected = false;
    this.isAuthenticated = false;
    this.reconnectAttempts = 0;
    // 从配置文件读取重连配置
    this.maxReconnectAttempts = websocketConfig.reconnect.maxAttempts;
    this.reconnectDelay = websocketConfig.reconnect.initialDelay;
    this.maxReconnectDelay = websocketConfig.reconnect.maxDelay;
    this.messageHandlers = [];
    this.pingInterval = null;
    this.cachedToken = null;
    // 从配置文件读取用户配置
    this.userPrefix = websocketConfig.user.prefix;
    this.platform = websocketConfig.user.platform;
  }

  getToken() {
    let token = uni.getStorageSync('token');
    if (token) {
      token = token.replace('Bearer ', '');
      this.cachedToken = token;
    }
    return token || null;
  }

  clearCachedToken() {
    this.cachedToken = null;
  }

  rebindUser() {
    const userId = uni.getStorageSync('doctor_id') || uni.getStorageSync('user_id');
    if (!userId) {
      console.warn('重新绑定用户失败：doctor_id不存在');
      return false;
    }
    
    this.clearCachedToken();
    
    if (this.isConnected) {
      return this.bindUser(userId, true);
    } else {
      this.connect();
      return true;
    }
  }

  connect() {
    if (this.isConnected) return;

    console.log('正在连接WebSocket...');
    this.socket = uni.connectSocket({
      url: this.url,
      success: () => {
        console.log('WebSocket连接成功');
      },
      fail: (err) => {
        console.error('WebSocket连接失败:', err);
        this.handleReconnect();
      }
    });

    this.socket.onOpen(() => {
      console.log('WebSocket连接已打开');
      this.isConnected = true;
      this.reconnectAttempts = 0;

      this.startHeartbeat();

      // 绑定当前用户（医生小程序使用doctor-前缀）
      const userId = uni.getStorageSync('doctor_id') || uni.getStorageSync('user_id');
      if (userId) {
        this.bindUser(userId, true);
      }
    });

    this.socket.onMessage((res) => {
      try {
        const data = JSON.parse(res.data);
        console.log('收到消息:', data);
        this.handleMessage(data);
      } catch (e) {
        console.error('解析消息失败:', e);
      }
    });

    this.socket.onClose((res) => {
      console.log('WebSocket连接关闭:', res);
      this.isConnected = false;
      this.stopHeartbeat();
      this.handleReconnect();
    });

    this.socket.onError((err) => {
      console.error('WebSocket错误:', err);
    });
  }

  unbindUser(userId) {
    const token = this.getToken();
    if (!token) {
      console.warn('解绑用户失败：token不存在');
      return false;
    }
    // 使用配置文件中的用户前缀
    const normalizedUserId = userId.toString().startsWith(this.userPrefix) ? userId : `${this.userPrefix}${userId}`;
    console.log('发送unbind请求，清理旧连接:', normalizedUserId);
    return this.send({
      request_type: 'unbind',
      user_type: 'doctor',
      sender_user_id: normalizedUserId,
      token: token
    }, false);
  }

  bindUser(userId, cleanOldConnections = true) {
    const token = this.getToken();
    if (!token) {
      console.error('绑定用户失败：token不存在');
      return false;
    }
    
    // 使用配置文件中的用户前缀
    const normalizedUserId = userId.toString().startsWith(this.userPrefix) ? userId : `${this.userPrefix}${userId}`;
    
    // 构建bind请求对象
    const bindMessage = {
      request_type: 'bind',
      user_type: 'doctor',
      sender_user_id: normalizedUserId,
      token: token,
      platform: this.platform, // 使用配置文件中的平台标识
      clean_old_connections: cleanOldConnections
    };
    
    // 输出详细的调试日志
    console.log('========== WebSocket Bind 请求 ==========');
    console.log('用户ID:', normalizedUserId);
    console.log('用户类型:', 'doctor');
    console.log('平台标识:', this.platform);
    console.log('清理旧连接:', cleanOldConnections);
    console.log('Token存在:', !!token);
    console.log('完整请求内容:', JSON.stringify(bindMessage, null, 2));
    console.log('==========================================');
    
    return this.send(bindMessage);
  }

  send(message, requireAuth = true) {
    if (!this.isConnected) {
      console.error('WebSocket未连接');
      return false;
    }

    try {
      if (requireAuth && !message.token && message.request_type !== 'ping') {
        const token = this.getToken();
        if (token) {
          message.token = token;
        }
      }

      // 如果是发送消息，确保添加platform标识
      if (message.request_type === 'send_message' && !message.platform) {
        message.platform = this.platform;
      }

      const messageStr = JSON.stringify(message);
      this.socket.send({
        data: messageStr,
        success: () => {
          console.log('消息发送成功:', message);
        },
        fail: (err) => {
          console.error('消息发送失败:', err);
        }
      });
      return true;
    } catch (err) {
      console.error('发送消息出错:', err);
      return false;
    }
  }

  addMessageHandler(handler) {
    this.messageHandlers.push(handler);
  }

  removeMessageHandler(handler) {
    const index = this.messageHandlers.indexOf(handler);
    if (index !== -1) {
      this.messageHandlers.splice(index, 1);
    }
  }

  handleMessage(data) {
    if (data.auth_status !== undefined) {
      if (data.auth_status === 'success') {
        console.log('========== WebSocket 认证成功 ==========');
        console.log('认证状态:', data.auth_status);
        console.log('完整响应:', JSON.stringify(data, null, 2));
        console.log('========================================');
        this.isAuthenticated = true;
      } else if (data.auth_status === 'failed') {
        console.error('========== WebSocket 认证失败 ==========');
        console.error('认证状态:', data.auth_status);
        console.error('错误消息:', data.message || '未知错误');
        console.error('错误代码:', data.code || '无');
        console.error('完整响应:', JSON.stringify(data, null, 2));
        console.error('当前用户ID:', uni.getStorageSync('doctor_id') || uni.getStorageSync('user_id'));
        console.error('Token存在:', !!this.getToken());
        console.error('平台标识:', this.platform);
        console.error('========================================');
        this.isAuthenticated = false;
        this.cachedToken = null;
      } else if (data.auth_status === 'token_expired') {
        console.warn('========== Token 已过期 ==========');
        console.warn('认证状态:', data.auth_status);
        console.warn('错误消息:', data.message || 'Token已过期');
        console.warn('完整响应:', JSON.stringify(data, null, 2));
        console.warn('==================================');
        this.isAuthenticated = false;
        this.cachedToken = null;
        uni.$emit('ws-token-expired');
        const userId = uni.getStorageSync('doctor_id') || uni.getStorageSync('user_id');
        if (userId) {
          console.log('尝试重新绑定用户...');
          this.bindUser(userId, true);
        }
      } else {
        console.warn('========== 未知的认证状态 ==========');
        console.warn('认证状态:', data.auth_status);
        console.warn('完整响应:', JSON.stringify(data, null, 2));
        console.warn('==================================');
      }
      return;
    }

    if (data.clientId) {
      const userId = uni.getStorageSync('doctor_id') || uni.getStorageSync('user_id');
      if (userId) {
        this.bindUser(userId, true);
      }
    }

    this.messageHandlers.forEach(handler => {
      try {
        handler(data);
      } catch (e) {
        console.error('消息处理出错:', e);
      }
    });
  }

  /**
   * 启动心跳
   * 职责：按照配置的心跳间隔发送ping消息
   */
  startHeartbeat() {
    this.pingInterval = setInterval(() => {
      if (this.isConnected) {
        this.send({ request_type: 'ping' }, false);
      }
    }, websocketConfig.heartbeat.interval);
  }

  stopHeartbeat() {
    if (this.pingInterval) {
      clearInterval(this.pingInterval);
      this.pingInterval = null;
    }
  }

  /**
   * 处理重连
   * 职责：按照配置的重连策略进行重连
   */
  handleReconnect() {
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('已达到最大重连次数');
      return;
    }

    setTimeout(() => {
      this.reconnectAttempts++;
      // 使用指数退避策略，但不超过最大延迟
      this.reconnectDelay = Math.min(this.reconnectDelay * 2, this.maxReconnectDelay);
      console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
      this.connect();
    }, this.reconnectDelay);
  }

  disconnect() {
    if (this.socket) {
      this.socket.close();
      this.socket = null;
    }
    this.isConnected = false;
    this.stopHeartbeat();
  }
}

// 全局WebSocket实例
// 使用配置文件中的URL
export const webSocketManager = new WebSocketManager();
