import IIMHandler from "../interface/i-im-handler";
import ImApi from './../../../apis/im'

export default class WebSocketHandlerImp extends IIMHandler {
    constructor() {
        super();
        this._socket = null
        this.im_user_id = null
        this.options = null
        this.timer = null
    }

    register () {
        return ImApi.register({name: 'xu'}).then(res => {
            this.im_user_id = res.data.id
            return res
        })
    }

    /**
     * 创建WebSocket连接
     * 如：this.imWebSocket = new IMWebSocket();
     *    this.imWebSocket.createSocket({url: 'ws://10.4.97.87:8001'});
     * 如果你使用本地服务器来测试，那么这里的url需要用ws，而不是wss，因为用wss无法成功连接到本地服务器
     * @param options 建立连接时需要的配置信息，这里是传入的url，即你的服务端地址，端口号不是必需的。
     */
    createConnection({options = this.options}) {
        console.log( options.url)
        this._socket = wx.connectSocket({
            url: options.url,
            header: {
                'content-type': 'application/json'
            },
            method: 'GET',
            success: () => {
                console.log('成功连接')
            },
            fail: () => {
                console.log('连接失败')
            }
        });
        this.intervalSendMsg()
        this.options = options
        console.log(this.options, 'options')
        this._onSocketOpen();
        this._onSocketMessage();
        this._onSocketError();
        this._onSocketClose();
    }

    reconnect () {
        console.log(this.options, 'this.option')
        this._socket = wx.connectSocket({
            url: this.options.url,
            header: {
                'content-type': 'application/json'
            },
            method: 'GET'
        });
            this._onSocketOpen();
            this._onSocketMessage();
            this._onSocketError();
            this._onSocketClose();
        console.log('重新连接')
    }
    _sendMsgImp({content, success, fail}) {
       
        console.log(content, 'content')
        this._socket.send({
            data: JSON.stringify(content),
            success: () => {
                success && success({content});
            },
            fail: (res) => {
                console.log(res, 'error')
                if (res.errMsg === 'SocketTask.send:fail SocketTask.readyState is not OPEN') {
                    // 发送消息失败，重新连接socket
                    this.closeConnection()
                    this.createConnection({options: this.options})
                }
                fail && fail(res);
            }
        });
    }


    /**
     * 关闭webSocket
     */
    closeConnection() {
        console.log('关闭socket')
        this._socket && this._socket.close();
    }

    _onSocketError(cb) {
        this._socket.onError((res) => {
            // this._isLogin = false;
            
            this._socket = null
            console.log('WebSocket连接打开失败，请检查！', res);
        })
    }

    _onSocketClose(cb) {
        this._socket.onClose((res) => {
            // 1分钟无消息后端自动断开连接，code 1006 需要重连socket
            if (res.code === 1006) {
                this._socket = wx.connectSocket({
                    url: this.options.url,
                    success: (res) => {
                        console.log('重连成功', res)
                    },
                    fail: (err) => {
                        console.log('重连失败', err)
                    }
                });
                return
            }
            clearInterval(this.timer)
            this.timer = null
            console.log('WebSocket 已关闭！', res)
            
        });
    }

    _onSocketOpen() {
        ImApi.getContacts(getApp().globalData.userinfo.user_id)
        this._socket.onOpen((res) => {
            console.log('WebSocket连接已打开！');
        });
    }

    /**
     * webSocket是在这里接收消息的
     * 在socket连接成功时，服务器会主动给客户端推送一条消息类型为login的信息，携带了用户的基本信息，如id，头像和昵称。
     * 在login信息接收前发送的所有消息，都会被推到msgQueue队列中，在登录成功后会自动重新发送。
     * 这里我进行了事件的分发，接收到非login类型的消息，会回调监听函数。
     * @private
     */
    _onSocketMessage() {
        this._socket.onMessage((res) => {
            console.log(res, 'receive msg')
            let msg = JSON.parse(res.data);
            if (msg.type === 'TYPE_ONE') {
                this._receiveListener.forEach(fn => {
                    fn(msg)
                })
                // this._receiveListener && this._receiveListener(msg);
            }
        })
    }

    intervalSendMsg () {
        this.timer = setInterval(() => {
            // 定时发消息，免得后端自动断开
            this._socket.send({data: JSON.stringify({content: '定时发消息'})})
        }, 50000);
    }

}
