import {checkDev} from "@/utils/utils";

export class WebSocketManager {
    constructor(url) {
        this.url = url;
        this.socket = null;
        this.isConnected = false;
        this.isAuthenticated = false; // 是否已认证
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectDelay = 1000;
        this.messageHandlers = [];
        this.pingInterval = null;
        this.cachedToken = null; // 缓存的token
    }

    /**
     * 获取当前用户的token
     * @returns {string|null}
     */
    getToken() {
        // 从本地存储获取token（不使用缓存，确保获取最新token）
        let token = uni.getStorageSync('token');
        if (token) {
            // 移除Bearer前缀（如果有）
            token = token.replace('Bearer ', '');
            this.cachedToken = token;
        }
        return token || null;
    }

    /**
     * 清除缓存的token（登录后需要调用，以获取最新token）
     */
    clearCachedToken() {
        this.cachedToken = null;
    }

    /**
     * 重新绑定用户（登录后调用）
     */
    rebindUser() {
        const userId = uni.getStorageSync('user_id');
        if (!userId) {
            console.warn('重新绑定用户失败：user_id不存在');
            return false;
        }
        
        // 清除缓存的token，确保获取最新token
        this.clearCachedToken();
        
        if (this.isConnected) {
            // 如果已连接，直接绑定
            return this.bindUser(userId);
        } else {
            // 如果未连接，先连接再绑定
            this.connect();
            // 连接成功后会在 onOpen 中自动绑定
            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();

            // 绑定当前用户（使用正确的key：user_id）
            const userId = uni.getStorageSync('user_id');
            if (userId) {
                this.bindUser(userId);
            }
        });

        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);
        });
    }

    /**
     * 绑定用户（携带token进行认证）
     * @param {string} userId 用户ID
     */
    bindUser(userId) {
        const token = this.getToken();
        if (!token) {
            console.error('绑定用户失败：token不存在');
            return false;
        }
        return this.send({
            request_type: 'bind',
            user_type: 'user',
            sender_user_id: userId,
            token: token
        });
    }

    /**
     * 发送消息（自动携带token）
     * @param {Object} message 消息对象
     * @param {boolean} requireAuth 是否需要认证（默认true）
     * @returns {boolean} 是否发送成功
     */
    send(message, requireAuth = true) {
        if (!this.isConnected) {
            console.error('WebSocket未连接');
            return false;
        }

        try {
            // 如果需要认证且消息中没有token，自动添加token
            if (requireAuth && !message.token && message.request_type !== 'ping') {
                const token = this.getToken();
                if (token) {
                    message.token = token;
                }
            }

            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);
        }
    }

    /**
     * 获取用户ID并绑定客户端（携带token）
     * @returns {string|null} 用户ID
     */
    getUserIdAndBindClientId() {
        const userId = uni.getStorageSync('user_id'); // 实际项目中从存储获取
        const token = this.getToken();
        
        if (userId == null || userId === 'user-' || userId === '') {
            // 等待10秒后重试
            setTimeout(() => {
                this.getUserIdAndBindClientId();
            }, 10000)
        } else if (!token) {
            // token不存在，等待后重试
            console.warn('token不存在，等待后重试绑定');
            setTimeout(() => {
                this.getUserIdAndBindClientId();
            }, 5000)
        } else {
            const bindMessage = {
                request_type: 'bind',
                user_type: 'user',
                sender_user_id: `user-${userId}`,
                token: token
            };
            this.send(bindMessage);
        }
        return userId;
    }

    handleMessage(data) {
        // 处理认证响应
        if (data.auth_status !== undefined) {
            if (data.auth_status === 'success') {
                console.log('WebSocket认证成功');
                this.isAuthenticated = true;
            } else if (data.auth_status === 'failed') {
                console.error('WebSocket认证失败:', data.message);
                this.isAuthenticated = false;
                // 清除缓存的token
                this.cachedToken = null;
            } else if (data.auth_status === 'token_expired') {
                console.warn('Token已过期，需要重新认证');
                this.isAuthenticated = false;
                this.cachedToken = null;
                // 通知应用层token过期
                uni.$emit('ws-token-expired');
                // 尝试重新绑定
                this.getUserIdAndBindClientId();
            }
            return;
        }

        // 如果对象中有clientId则给websocket发送绑定请求
        if (data.clientId) {
            this.getUserIdAndBindClientId(data.clientId);
        }

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

    startHeartbeat() {
        this.pingInterval = setInterval(() => {
            if (this.isConnected) {
                this.send({type: 'ping'});
            }
        }, 300000);
    }

    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, 30000);
            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实例
// export const webSocketManager = new WebSocketManager('ws://127.0.0.1:12080/ws');
const wsUrl = checkDev('dev')? 'ws://127.0.0.1:12080/ws':'wss://api.ws.g.xiaokang88.com/ws';
export const webSocketManager = new WebSocketManager(wsUrl);