// singleton
let instance = null;

module.exports = class GameServerConnection {
    constructor (opts) {
        if (instance) return instance;
        instance = this;
        this.address = opts.address || `ws://${window.location.hostname}:7000/game`;
        this.reconnectTimer = opts.reconnectTimer ? Number(opts.reconnectTimer) : 5000;
        this.agent = opts.agent;
    }

    connect () {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) return;
        this.ws = new WebSocket(this.address);
        this.connectionRetries = this.connectionRetries || [];
        this.agent.connect(this.ws);

        this.ws.onopen = () => {
            this.connectionRetries.forEach(r => clearTimeout(r));
            this.connectionRetries = [];
        };

        this.ws.onclose = e => {
            // eslint-disable-next-line no-console
            console.log('Socket is closed. Reconnect will be attempted every 5 seconds.', e.reason);
            this.connectionRetries.push(setTimeout(() => {
                this.ws = null;
                this.connect();
            }, this.reconnectTimer));
        };

        this.ws.onerror = error => {
            // eslint-disable-next-line no-console
            console.log(`WebSocket error: ${error}`);
            this.disconnect();
        };

        this.ws.onmessage = e => {
            // eslint-disable-next-line no-console
            // console.log('onmessage', e.data);
            this.agent.handleMessage(e.data);
        };
    }

    disconnect () {
        if (this.ws) this.ws.close();
        if (this.connectionRetries) this.connectionRetries.forEach(r => clearTimeout(r));
    }
};
