class Connection {
    connectionTries = 0;
    ws;
    receiveCB;

    constructor(receiveCB) {
        this.receiveCB = receiveCB;
        this.init()
    }

    init = async () => {
        return new Promise((resolve, reject) => {
            const url = window.location.hostname.includes("local") 
                ? "ws://" + window.location.host 
                : "wss://" + window.location.hostname + window.location.pathname;

            this.ws = new WebSocket(url);

            this.ws.addEventListener('open', () => {
                this.connectionTries = 0;
                console.log("WebSocket connection established.");
                this.ws.addEventListener('message', this.receiveCB);
                resolve(this.ws); // resolve when open
            });

            this.ws.addEventListener('close', () => {
                console.log('WebSocket closed');
                this.checkOpen(); // attempt reconnection
            });

            this.ws.addEventListener('error', (err) => {
                console.error('WebSocket error', err);
                reject(err); // reject if error occurs
            });
        });
    }

    checkOpen = async () => {
        if (this.ws.readyState === WebSocket.OPEN) {
            return true;
        } else {
            await this.sleep(this.connectionTries < 20 ? 5000 : 60000);
            this.connectionTries++;
            console.log('Reestablishing connection');
            await this.init();
        }
    }

    sleep = (time) => new Promise(resolve => setTimeout(resolve, time));

    send = (msg) => {
        if (this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(msg);
        } else if (this.connectionTries === 0) {
            setTimeout(() => this.send(msg), 100);
        } else {
            console.error('No WebSocket connection: Cannot send message');
        }
    }
}

export default Connection;
