/*!
  * version-polling v1.2.6
  * (c) 2023 JoeshuTT
  * @license MIT
  */
function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
function _toPrimitive(input, hint) {
  if (typeof input !== "object" || input === null) return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== undefined) {
    var res = prim.call(input, hint || "default");
    if (typeof res !== "object") return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return typeof key === "symbol" ? key : String(key);
}

/**
 * 是否有值
 * @param {*} val
 */
/**
 * 创建一个 Web Work 实例
 * @param func
 */
function createWorker(func) {
  const blob = new Blob(["(" + func.toString() + ")()"]);
  const url = window.URL.createObjectURL(blob);
  const worker = new Worker(url);
  window.URL.revokeObjectURL(url);
  return worker;
}
function createWorkerFunc() {
  let timerId = null;
  let options;
  self.onmessage = event => {
    let code = event.data["code"];
    options = Object.assign({}, options, event.data["data"]);
    const {
      htmlFileUrl,
      lastEtag,
      appETagKey,
      pollingInterval,
      silentPollingInterval
    } = options;
    const runReq = () => {
      fetch(htmlFileUrl, {
        method: "HEAD",
        cache: "no-cache"
      }).then(response => {
        if (Number(response.status) !== 200) {
          return;
        }
        const etag = response.headers.get("etag");
        if (lastEtag !== etag) {
          self.postMessage({
            appETagKey,
            lastEtag,
            etag
          });
        }
      });
    };
    const startPollingTask = () => {
      timerId = setInterval(runReq, pollingInterval);
    };
    const pausePollingTask = () => {
      if (timerId) {
        clearInterval(timerId);
        timerId = null;
      }
    };
    if (code === "pause") {
      pausePollingTask();
    } else {
      runReq(); // 立即执行一次
      if (!silentPollingInterval) {
        startPollingTask();
      }
    }
  };
  return self;
}
function closeWorker(worker) {
  worker.terminate();
}

let APP_ETAG_KEY = "__APP_ETAG__";
let myWorker;
const defaultOptions = {
  appETagKey: APP_ETAG_KEY,
  pollingInterval: 5 * 60 * 1000,
  htmlFileUrl: `${location.origin}${location.pathname}`,
  silent: false,
  silentPollingInterval: false,
  silentPageVisibility: false,
  forceUpdate: false
};
let attached = false;
/**
 * 页面隐藏时停止轮询任务，页面再度可见时在继续
 */
function handleVisibilityChange() {
  if (document.visibilityState === "visible") {
    myWorker.postMessage({
      code: "resume"
    });
  } else {
    myWorker.postMessage({
      code: "pause"
    });
  }
}
class VersionPolling {
  constructor(options) {
    _defineProperty(this, "options", void 0);
    _defineProperty(this, "appEtag", "");
    this.options = Object.assign({}, defaultOptions, options);
    this.init();
  }
  async init() {
    const {
      htmlFileUrl
    } = this.options;
    if (!htmlFileUrl) {
      throw new Error("[version-polling]: htmlFileUrl is required");
    }
    const response = await fetch(htmlFileUrl, {
      method: "HEAD",
      cache: "no-cache"
    });
    if (Number(response.status) !== 200) {
      throw new Error(`[version-polling]: status is ${response.status}`);
    }
    const etag = response.headers.get("etag");
    // eslint-disable-next-line no-eq-null
    if (etag == null) {
      throw new Error(`[version-polling]: etag is null`);
    }
    this.appEtag = etag;
    localStorage.setItem(`${this.options.appETagKey}`, etag);
    this.start();
  }
  start() {
    const {
      appETagKey,
      pollingInterval,
      htmlFileUrl,
      silent,
      silentPollingInterval,
      silentPageVisibility
    } = this.options;
    if (silent) {
      return;
    }
    myWorker = createWorker(createWorkerFunc);
    myWorker.postMessage({
      code: "start",
      data: {
        appETagKey,
        pollingInterval,
        htmlFileUrl,
        silentPollingInterval,
        lastEtag: this.appEtag
      }
    });
    myWorker.onmessage = event => {
      const {
        lastEtag,
        etag
      } = event.data;
      if (lastEtag !== etag) {
        this.stop();
        this.options.onUpdate(this);
      }
    };
    if (!silentPageVisibility) {
      if (!attached) {
        document.addEventListener("visibilitychange", handleVisibilityChange);
        attached = true;
      }
    }
  }
  stop() {
    if (myWorker) {
      closeWorker(myWorker);
      if (attached) {
        document.removeEventListener("visibilitychange", handleVisibilityChange);
        attached = false;
      }
    }
  }
  onRefresh() {
    window.location.reload();
  }
  onCancel() {
    this.options.forceUpdate && this.start();
  }
}
function createVersionPolling(options) {
  const versionPolling = new VersionPolling(options);
  return versionPolling;
}

export { VersionPolling, createVersionPolling };
