/**
 * WebSocket 管理器类
 * 用于管理 WebSocket 连接、心跳机制、消息收发等功能
 */
export default class WebSocketManager {
    private socket: WebSocket | null = null; // WebSocket 对象
    private pingTimeout: number | null = null; // 心跳计时器
    private reconnectTimeout: number | null = null; // 重连计时器
    private reconnectTimeoutClock: number = 5000; // 重连间隔，单位：毫秒
    private maxReconnectAttempts: number = 5; // 最大重连尝试次数
    private reconnectAttempts: number = 0; // 当前重连尝试次数
    private url: string; // WebSocket 连接地址
    private receiveMessageCallback: ((data: any) => void) | null = null; // 接收消息回调函数

    /**
     * 构造函数
     * @param url WebSocket 连接地址
     * @param receiveMessageCallback 接收消息的回调函数
     */
    constructor(url: string | null = null, receiveMessageCallback: ((data: any) => void) | null = null) {
        if (!url) {
            console.error('WebSocketManager error: 请传入有效的连接地址');
            throw new Error('WebSocket URL is required');
        }
        
        this.url = url;
        this.receiveMessageCallback = receiveMessageCallback;
    }

    /**
     * 启动 WebSocket 连接
     */
    async start(): Promise<void> {
        if (this.url) {
            // 连接 WebSocket
            this.connectWebSocket();
        } else {
            console.error('WebSocketManager error: 连接地址无效');
        }
    }

    /**
     * 获取 WebSocket 连接状态
     * @returns WebSocket 的 readyState
     */
    getSocketStatus(): number {
        return this.socket?.readyState ?? WebSocket.CLOSED;
    }

    /**
     * 创建 WebSocket 连接
     */
    private connectWebSocket(): void {
        try {
            // 创建 WebSocket 对象
            this.socket = new WebSocket(this.url);

            // 处理连接打开事件
            this.socket.addEventListener('open', () => {
                console.log('WebSocket 连接成功');
                // 启动心跳机制
                this.startHeartbeat();
                // 重置重连次数
                this.reconnectAttempts = 0;
            });

            // 处理接收到消息事件
            this.socket.addEventListener('message', (event: MessageEvent) => {
                this.receiveMessage(event);
            });

            // 处理连接关闭事件
            this.socket.addEventListener('close', (event: CloseEvent) => {
                console.log(`WebSocket 连接关闭, code: ${event.code}, reason: ${event.reason}`);
                // 清除定时器
                this.clearTimers();
                
                // 尝试重连
                if (this.reconnectAttempts < this.maxReconnectAttempts) {
                    this.reconnectAttempts++;
                    console.log(`尝试第 ${this.reconnectAttempts} 次重连...`);
                    
                    this.reconnectTimeout = window.setTimeout(() => {
                        this.connectWebSocket();
                    }, this.reconnectTimeoutClock);
                } else {
                    // 重置重连次数
                    this.reconnectAttempts = 0;
                    console.error('WebSocketManager error: 已达到最大重连尝试次数，无法重新连接');
                }
            });

            // 处理 WebSocket 错误事件
            this.socket.addEventListener('error', (event: Event) => {
                console.error('WebSocketManager error: 连接发生错误', event);
            });
        } catch (error) {
            console.error('WebSocketManager error: 创建连接失败', error);
        }
    }

    /**
     * 启动心跳机制
     * 每隔 10 秒发送一次心跳消息，保持连接活跃
     */
    private startHeartbeat(): void {
        // 先清除已存在的心跳定时器
        this.clearPingTimeout();
        
        this.pingTimeout = window.setInterval(() => {
            // 发送心跳消息
            this.sendOrderMessage('heartCheck');
        }, 10000); // 每隔 10 秒发送一次心跳
    }

    /**
     * 发送消息
     * @param message 消息内容
     */
    sendOrderMessage(message: string): void {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
            this.socket.send(message);
        } else {
            console.error('WebSocketManager error: WebSocket 连接未打开，无法发送消息');
        }
    }

    /**
     * 处理接收到的消息
     * @param event MessageEvent 对象
     */
    private receiveMessage(event: MessageEvent): void {
        const data = event.data;
        
        // 处理心跳消息
        if (data === 'heartCheck') {
            // 收到心跳响应，无需处理
            return;
        }
        
        // 调用回调函数处理业务消息
        if (this.receiveMessageCallback && typeof this.receiveMessageCallback === 'function') {
            try {
                this.receiveMessageCallback(data);
            } catch (error) {
                console.error('WebSocketManager error: 消息回调处理失败', error);
            }
        }
    }

    /**
     * 关闭 WebSocket 连接
     */
    closeWebSocket(): void {
        if (this.socket) {
            this.socket.close();
            this.socket = null;
        }
        
        // 清除所有定时器
        this.clearTimers();
        
        // 重置重连次数
        this.reconnectAttempts = 0;
        
        console.log('WebSocket 连接已手动关闭');
    }

    /**
     * 清除心跳定时器
     */
    private clearPingTimeout(): void {
        if (this.pingTimeout !== null) {
            clearInterval(this.pingTimeout);
            this.pingTimeout = null;
        }
    }

    /**
     * 清除重连定时器
     */
    private clearReconnectTimeout(): void {
        if (this.reconnectTimeout !== null) {
            clearTimeout(this.reconnectTimeout);
            this.reconnectTimeout = null;
        }
    }

    /**
     * 清除所有定时器
     */
    private clearTimers(): void {
        this.clearPingTimeout();
        this.clearReconnectTimeout();
    }

    /**
     * 销毁实例，清理资源
     */
    destroy(): void {
        this.closeWebSocket();
        this.receiveMessageCallback = null;
    }
}