(function (root, factory) {
  if (typeof module === 'object' && module.exports) module.exports = factory;
  else root.createMobileInsights = factory;
})(typeof self !== 'undefined' ? self : this, function (o) {
  const route = '#/insights';
  const events = o.eventTarget || self;
  const location = o.location || self.location;
  let active = false;
  let previous = '#/my-work';
  let retries = 0;

  function attr(element, name, value) {
    if (value === null) element.removeAttribute(name);
    else element.setAttribute(name, value);
  }

  function render(open, focus = false) {
    const wasActive = active;
    active = Boolean(open && o.mediaQuery.matches);
    const detour = active ? o.detour?.() : null;
    const started = detour?.beginDetour('insights');
    if (detour && !started && retries++ < 40) setTimeout(sync, 250);
    else if (started && retries) { retries = 0; setTimeout(sync, 500); }
    else retries = 0;
    if (wasActive && !active) o.detour?.()?.finishDetour();
    attr(o.root, 'data-mobile-open', active ? 'true' : null);
    attr(o.root, 'role', active ? 'dialog' : null);
    attr(o.root, 'aria-modal', active ? 'true' : null);
    attr(o.root, 'aria-hidden', active || !o.mediaQuery.matches ? null : 'true');
    o.root.inert = !active && o.mediaQuery.matches;
    o.backgrounds.forEach(element => { element.inert = active; });
    o.dock.hidden = active;
    attr(o.hud, 'data-overlay-hidden', active ? 'true' : null);
    if (active) o.closeButton.focus();
    else if (focus) o.launcher.focus();
  }

  function url(hash) {
    return (location.pathname || '') + (location.search || '') + hash;
  }

  function open() {
    if (!o.mediaQuery.matches || active) return false;
    previous = location.hash && location.hash !== route ? location.hash : '#/my-work';
    const menu = o.menu || o.launcher.closest?.('details');
    if (menu) menu.open = false;
    o.history.pushState({ ...(o.history.state || {}), mobileInsights:true, previousHash:previous }, '', url(route));
    render(true);
    return true;
  }

  function sync() {
    render(location.hash === route, active && location.hash !== route);
  }

  function close() {
    if (!active) return false;
    if (o.history.state?.mobileInsights) o.history.back();
    else {
      const state = { ...(o.history.state || {}) };
      delete state.mobileInsights;
      delete state.previousHash;
      o.history.replaceState(state, '', url(previous));
      render(false, true);
    }
    return true;
  }

  function returnToToday() {
    if (!active) return false;
    const state = { ...(o.history.state || {}) };
    delete state.mobileInsights;
    delete state.previousHash;
    o.history.replaceState(state, '', url(previous));
    render(false);
    return true;
  }

  function start() {
    o.launcher.addEventListener('click', open);
    o.closeButton.addEventListener('click', close);
    (o.returnButton || o.root.querySelector?.('[data-return-from-detour]'))?.addEventListener('click', returnToToday);
    events.addEventListener('popstate', sync);
    events.addEventListener('hashchange', sync);
    events.addEventListener('keydown', event => {
      if (active && event.key === 'Escape') {
        event.preventDefault?.();
        close();
      }
    });
    o.mediaQuery.addEventListener?.('change', sync);
    sync();
  }

  return { start, open, close, sync, current:() => active };
});
