// retoor <retoor@molodetz.nl>

const WRONG_WORKER_CODE = 4013;
const WRONG_WORKER_RETRY_MS = 200;
const RECONNECT_DELAY_MS = 1500;

export class SeoProgressSocket {
    constructor(uid, handlers) {
        this.handlers = handlers || {};
        this.ws = null;
        this._shouldRun = true;
        const scheme = location.protocol === "https:" ? "wss://" : "ws://";
        this.url = `${scheme}${location.host}/tools/seo/${encodeURIComponent(uid)}/ws`;
    }

    connect() {
        this._shouldRun = true;
        this._open();
    }

    _open() {
        this.ws = new WebSocket(this.url);
        this.ws.addEventListener("message", (event) => {
            let frame;
            try {
                frame = JSON.parse(event.data);
            } catch {
                return;
            }
            this._emit("onMessage", frame);
        });
        this.ws.addEventListener("close", (event) => {
            if (event.code === WRONG_WORKER_CODE && this._shouldRun) {
                window.setTimeout(() => this._open(), WRONG_WORKER_RETRY_MS);
                return;
            }
            this._emit("onClose");
        });
        this.ws.addEventListener("error", () => this._emit("onError"));
    }

    close() {
        this._shouldRun = false;
        if (this.ws) this.ws.close();
    }

    _emit(name, payload) {
        const handler = this.handlers[name];
        if (typeof handler === "function") handler(payload);
    }
}
