import { ref } from 'vue'
import eventBus from '@/utils/eventBus'

// 标志位区分是手动断开还是意外断开
let isManualDisconnect = false

export const useWebSocket = {
    socket: null as WebSocket | null, // 声明
    isConnected: ref(false), // 判断当前连接状态
    reconnectAttempts: 0, // 当前重连数
    maxReconnectAttempts: 5, // 最大重连数
    reconnectInterval: 3000, // 重连间隔
    lastUrl: '', // 保存最后连接的URL

    // 连接 WebSocket 服务器,监听相关事件
    connect(url: string) {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
            return
        }

        this.lastUrl = url
        this.socket = new WebSocket(url)

        this.socket.onopen = () => {
            this.isConnected.value = true
            this.reconnectAttempts = 0
            heartCheck.start()
            console.log('WebSocket连接已打开')
        }

        this.socket.onclose = () => {
            this.isConnected.value = false
            console.log('WebSocket连接已关闭')
            heartCheck.stop()
            if (!isManualDisconnect) {
                this.reconnect(url)
            }
        }

        this.socket.onerror = (error: Event) => {
            console.error('WebSocket error:', error)
        }

        this.socket.onmessage = (event: MessageEvent) => {
            try {
                // console.log('收到消息:', event.data)
                const data = JSON.parse(event.data) || {}
                if (data.messageType) {
                    eventBus.emit('socketMsg', data)
                }
            } catch (error) {
                console.error('WebSocket消息解析错误:', error)
            }
        }
    },
    // 关闭链接
    disconnect() {
        isManualDisconnect = true
        heartCheck.stop()
        if (this.socket) {
            this.socket.close()
            this.socket = null
            this.isConnected.value = false
        }
        this.reconnectAttempts = 0
    },
    // 尝试重连
    reconnect(url?: string) {
        if (isManualDisconnect) {
            console.log('主动断开，无需重连')
            heartCheck.stop()
            return
        }
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++
            console.log(`重连次数 ${this.reconnectAttempts}`)
            // 清理旧连接
            if (this.socket) {
                this.socket = null
            }
            setTimeout(() => {
                this.connect(url || this.lastUrl || '')
            }, this.reconnectInterval)
        } else {
            console.error(`已达到最大重连次数${this.maxReconnectAttempts}，放弃重连`)
            heartCheck.stop()
        }
    },
    // 发送消息
    sendMessage(message: string) {
        if (this.isConnected.value && this.socket) {
            this.socket.send(message)
            // console.log('WebSocket 消息发送成功:', message)
        } else {
            console.error('WebSocket 连接未打开，无法发送消息')
        }
    },

    getReadyState() {
        if (!this.socket) return ''
        return this.socket.readyState
    }
}

export const heartCheck = {
    timeout: null as NodeJS.Timeout | null, // 更具体的类型
    timeoutInterval: 60000, // 心跳超时时间

    start() {
        if (this.timeout) {
            console.warn('心跳检测已经启动')
            return
        }
        this.timeout = setInterval(() => {
            this.check()
        }, this.timeoutInterval)
    },

    stop() {
        if (this.timeout) {
            clearInterval(this.timeout)
            this.timeout = null
            console.log('心跳检测已停止')
        } else {
            // console.warn('心跳检测未启动，无需停止')
        }
    },

    check() {
        const readyState = useWebSocket.getReadyState()
        if (readyState === WebSocket.CLOSED || readyState === WebSocket.CLOSING) {
            console.log('心跳检测readyState:', readyState)
            console.error('WebSocket 连接已断开，尝试重连')
            this.stop()
            useWebSocket.reconnect()
        } else if (readyState === WebSocket.OPEN) {
            this.sendPing()
        }
    },

    sendPing() {
        try {
            useWebSocket.sendMessage(JSON.stringify({ messageType: 'ping' }))
        } catch (error) {
            console.error('发送心跳消息时出错:', error)
            this.stop() // 停止心跳检测，如果消息发送失败，可能是连接已经断开
        }
    }
}

export function initWebSocket(url: string) {
    useWebSocket.connect(url)
}

export function destroyWebSocket() {
    isManualDisconnect = true
    heartCheck.stop()
    useWebSocket.disconnect()
}
