const r = 'SharedWorker' in globalThis;
class e {
  ActualWorker;
  constructor(e, t) {
    this.ActualWorker = r ? new SharedWorker(e, t) : new Worker(e, t);
  }
  get onmessage() {
    return r ? this.ActualWorker?.port.onmessage : this.ActualWorker.onmessage;
  }
  set onmessage(e) {
    r
      ? (this.ActualWorker.port.onmessage = e)
      : (this.ActualWorker.onmessage = e);
  }
  get onmessageerror() {
    return r
      ? this.ActualWorker?.port.onmessageerror
      : this.ActualWorker.onmessageerror;
  }
  set onmessageerror(e) {
    r
      ? (this.ActualWorker.port.onmessageerror = e)
      : (this.ActualWorker.onmessageerror = e);
  }
  start() {
    if (r) return this.ActualWorker?.port.start();
  }
  postMessage(e, t) {
    return r
      ? this.ActualWorker?.port.postMessage(e, t)
      : this.ActualWorker.postMessage(e, t);
  }
  terminate() {
    return r ? this.ActualWorker?.port.close() : this.ActualWorker.terminate();
  }
  close() {
    return this.terminate();
  }
  get port() {
    return r ? this.ActualWorker.port : this.ActualWorker;
  }
  get onerror() {
    return this.ActualWorker.onerror;
  }
  set onerror(r) {
    this.ActualWorker.onerror = r;
  }
  addEventListener(e, t, o) {
    return r && 'error' !== e
      ? this.ActualWorker?.port.addEventListener(e, t, o)
      : this.ActualWorker.addEventListener(e, t, o);
  }
  removeEventListener(e, t, o) {
    return r && 'error' !== e
      ? this.ActualWorker?.port.removeEventListener(e, t, o)
      : this.ActualWorker.removeEventListener(e, t, o);
  }
  dispatchEvent(r) {
    return this.ActualWorker.dispatchEvent(r);
  }
}
if (!r) {
  window.SharedWorker = e;
  SharedWorker = e;
}

// export { e as SharedWorkerPolyfill, r as SharedWorkerSupported, e as default };

(function(global) {
  var channels = [];

  function BroadcastChannel(channel) {
    var $this = this;
    channel = String(channel);

    var id = '$BroadcastChannel$' + channel + '$';

    channels[id] = channels[id] || [];
    channels[id].push(this);

    this._name = channel;
    this._id = id;
    this._closed = false;
    this._mc = new MessageChannel();
    this._mc.port1.start();
    this._mc.port2.start();

    global.addEventListener('storage', function(e) {
      if (e.storageArea !== global.localStorage) return;
      if (e.newValue === null) return;
      if (e.key.substring(0, id.length) !== id) return;
      var data = JSON.parse(e.newValue);
      $this._mc.port2.postMessage(data);
    });
  }

  BroadcastChannel.prototype = {
    // BroadcastChannel API
    get name() {
      return this._name;
    },
    postMessage: function(message) {
      var $this = this;
      if (this._closed) {
        var e = new Error();
        e.name = 'InvalidStateError';
        throw e;
      }
      var value = JSON.stringify(message);

      // Broadcast to other contexts via storage events...
      var key = this._id + String(Date.now()) + '$' + String(Math.random());
      global.localStorage.setItem(key, value);
      setTimeout(function() {
        global.localStorage.removeItem(key);
      }, 500);

      // Broadcast to current context via ports
      channels[this._id].forEach(function(bc) {
        if (bc === $this) return;
        bc._mc.port2.postMessage(JSON.parse(value));
      });
    },
    close: function() {
      if (this._closed) return;
      this._closed = true;
      this._mc.port1.close();
      this._mc.port2.close();

      var index = channels[this._id].indexOf(this);
      channels[this._id].splice(index, 1);
    },

    // EventTarget API
    get onmessage() {
      return this._mc.port1.onmessage;
    },
    set onmessage(value) {
      this._mc.port1.onmessage = value;
    },
    addEventListener: function(type, listener /*, useCapture*/) {
      return this._mc.port1.addEventListener.apply(this._mc.port1, arguments);
    },
    removeEventListener: function(type, listener /*, useCapture*/) {
      return this._mc.port1.removeEventListener.apply(
        this._mc.port1,
        arguments
      );
    },
    dispatchEvent: function(event) {
      return this._mc.port1.dispatchEvent.apply(this._mc.port1, arguments);
    }
  };

  global.BroadcastChannel = global.BroadcastChannel || BroadcastChannel;
})(self);

let webSocketState;
let websocketPath = 'workers/sharedWorker.js?version=2';

if (typeof SharedWorker == 'undefined') {
  const worker = new Worker(
    location.origin + location.pathname + websocketPath,
    {
      name: 'SuperShare'
    }
  );

  worker.onmessage = (event) => {
    switch (event.data.type) {
      case 'WSState':
        webSocketState = event.data.state;
        break;
      case 'message':
        handleMessageFromPort(event.data);
        break;
    }
  };
} else {
  const worker = new SharedWorker(
    location.origin + location.pathname + websocketPath,
    {
      name: 'SuperShare'
    }
  );

  let portableworker;
  if (worker.port !== undefined) {
    portableworker = worker.port;
    if (portableworker && portableworker?.start) {
      portableworker.start();
    }
  } else {
    portableworker = worker;
  }

  portableworker.onmessage = (event) => {
    switch (event.data.type) {
      case 'WSState':
        webSocketState = event.data.state;
        break;
      case 'message':
        handleMessageFromPort(event.data);
        break;
    }
  };
}

const broadcastChannel = new BroadcastChannel('SuperShare');
broadcastChannel.addEventListener('message', (event) => {
  switch (event.data.type) {
    case 'WSState':
      webSocketState = event.data.state;
      break;
    case 'message':
      handleBroadcast(event.data);

      break;
  }
});

// Listen to broadcasts from server
function handleBroadcast(data) {
  console.log('This message is meant for everyone!');
  console.log(data);
}

// Handle event only meant for this tab
function handleMessageFromPort(data) {
  console.log(`This message is meant only for user with id: ${id}`);
  console.log(data);
}
