/**
 * 封装uniapp的WebSocket对象，使其与原生类似，供stomp使用
 */
class UniWebSocket {
    ws: UniApp.SocketTask
    activeClose: boolean
    openListener: Function[]
    closeListener: Function[]
    errorListener: Function[]
    messageListener: Function[]

    constructor(url: string, protocols: string[]) {
        // 是否主动关闭连接
        this.activeClose = false

        // 相关事件数组
        this.openListener = []
        this.closeListener = []
        this.errorListener = []
        this.messageListener = []

        // 创建连接
        const ws = uni.connectSocket({
            url,
            protocols,
            complete: () => {},
        })

        // 连接开启
        ws.onOpen((res) => {
            this.onopen(res)
            for (const i in this.openListener) {
                this.openListener[i](res)
            }
        })

        // 连接关闭
        ws.onClose((res) => {
            // 主动关闭连接不进行回调
            if (this.activeClose) {
                this.activeClose = false
            } else {
                this.onclose(res)
            }
            for (const i in this.closeListener) {
                this.closeListener[i](res)
            }
        })

        // 连接异常
        ws.onError((res) => {
            this.onerror(res)
            for (const i in this.errorListener) {
                this.errorListener[i](res)
            }
        })

        // 接收消息
        ws.onMessage((res) => {
            this.onmessage(res)
            for (const i in this.messageListener) {
                this.messageListener[i](res)
            }
        })

        this.ws = ws
    }

    /**
     * 添加监听
     * @param {string} eventName
     * @param {Function} callback
     */
    addEventListener(eventName: string, callback: Function) {
        if (eventName === 'open') {
            this.openListener.push(callback)
        } else if (eventName === 'close') {
            this.closeListener.push(callback)
        } else if (eventName === 'error') {
            this.errorListener.push(callback)
        } else if (eventName === 'message') {
            this.messageListener.push(callback)
        }
    }

    /**
     * 移除最后一个监听
     * @param {string} eventName
     */
    removeEventListener(eventName: string) {
        if (eventName === 'open') {
            this.openListener.pop()
        } else if (eventName === 'close') {
            this.closeListener.pop()
        } else if (eventName === 'error') {
            this.errorListener.pop()
        } else if (eventName === 'message') {
            this.messageListener.pop()
        }
    }

    /**
     * 连接开启
     * @param {object} _res
     */
    onopen(_res: object) {}

    /**
     * 连接关闭
     * @param {object} _res
     */
    onclose(_res: object) {}

    /**
     * 连接异常
     * @param {object} _res
     */
    onerror(_res: object) {}

    /**
     * 接收消息
     * @param {object} _res
     */
    onmessage(_res: object) {}

    /**
     * 发送消息
     * @param {string | ArrayBuffer} data
     */
    send(data: string | ArrayBuffer) {
        this.ws.send({
            data,
        })
    }

    /**
     * 关闭连接
     */
    close() {
        this.activeClose = true
        this.ws.close({
            complete: () => {},
        })
    }
}

export default UniWebSocket
