(function (root, factory) {
  if (typeof module === 'object' && module.exports) module.exports = factory;
  else root.createMobileFirstTask = factory;
})(typeof self !== 'undefined' ? self : this, function createMobileFirstTask(options) {
  const doc = typeof document !== 'undefined' ? document : null;
  const win = typeof window !== 'undefined' ? window : null;
  options = Object.assign({
    storage: typeof localStorage !== 'undefined' ? localStorage : null,
    isOnline: () => typeof navigator === 'undefined' || navigator.onLine,
    mediaQuery: win?.matchMedia('(max-width: 600px)') || {matches:false},
    eventTarget: win,
    setTimer: (...args) => globalThis.setTimeout(...args),
    sheet: doc?.querySelector('#mobile-first-task'),
    title: doc?.querySelector('#mobile-first-task-title'),
    findButton: doc?.querySelector('#mobile-first-task-find'),
    createButton: doc?.querySelector('#mobile-first-task-create'),
    setupButton: doc?.querySelector('#mobile-first-task-setup'),
    closeButton: doc?.querySelector('#close-mobile-first-task'),
    status: doc?.querySelector('#mobile-first-task-status'),
    coach: doc?.querySelector('[data-mobile-first-task-coach]'),
    receipt: doc?.querySelector('#mobile-first-task-receipt'),
    isTodayActive: () => false,
    onFind: () => doc?.querySelector('#find-work')?.click(),
    onCreate: () => doc?.querySelector('#new-issue')?.click(),
    onSetup: () => doc?.querySelector('#open-device-setup')?.click(),
  }, options);
  const prefix = 'stackchain.first-task.v1:';

  function account() {
    return String(options.getLogin?.() || '').trim().toLowerCase();
  }

  function key() {
    const login = account();
    return login ? prefix + login : '';
  }

  function state() {
    const currentKey = key();
    if (!currentKey) return '';
    try { return options.storage.getItem(currentKey) || ''; }
    catch (_error) { return ''; }
  }

  function store(value) {
    const currentKey = key();
    const current = state();
    if (!currentKey || current === value || current === 'complete') return false;
    try {
      options.storage.setItem(currentKey, value);
      return true;
    } catch (_error) { return false; }
  }

  function adoptRemote(value) {
    return ['coaching', 'complete'].includes(value) && store(value);
  }

  function required() {
    return Boolean(options.mediaQuery.matches && account() && !options.isTodayActive() && !state());
  }

  function renderCoach() {
    if (!options.coach) return;
    options.coach.hidden = !(options.mediaQuery.matches && state() === 'coaching' && options.isTodayActive());
  }

  function render() {
    const online = options.isOnline();
    const awaitingStart = options.hasWork();
    options.findButton.disabled = !online;
    if (options.title) options.title.textContent = awaitingStart ? 'Finish starting your first task' : 'Start your first task';
    options.findButton.textContent = 'Find & start';
    options.createButton.textContent = 'Create & start';
    options.status.textContent = awaitingStart ?
      'Your task is ready. Start it from Find or create and start another task.' : online ?
      'Choose a task to claim and start, or create and start one of your own.' :
      'You are offline. Create a task now and it will stay in Drafts until you reconnect.';
  }

  function open() {
    if (!required()) return false;
    render();
    if (!options.sheet.open) options.sheet.showModal();
    (options.findButton.disabled ? options.createButton : options.findButton).focus();
    return true;
  }

  function refresh() {
    if (account() && options.isTodayActive() && state() !== 'complete') {
      store('coaching');
      if (options.sheet.open) options.sheet.close();
      renderCoach();
      return 'coaching';
    }
    renderCoach();
    if (options.sheet.open) render();
    if (required() && options.hasWork()) return 'awaiting-start';
    return required() ? 'required' : 'inactive';
  }

  function completeOutcome() {
    if (state() !== 'coaching') return false;
    store('complete');
    options.eventTarget?.dispatchEvent?.(new CustomEvent('stackchain:first-task-complete'));
    renderCoach();
    if (options.receipt) {
      options.receipt.hidden = false;
      options.setTimer?.(() => { options.receipt.hidden = true; }, 6000);
    }
    return true;
  }

  function handoff(callback, requiresOnline = false) {
    if (requiresOnline && !options.isOnline()) return;
    if (options.sheet.open) options.sheet.close();
    callback();
  }

  function start() {
    options.findButton.addEventListener('click', () => handoff(options.onFind, true));
    options.createButton.addEventListener('click', () => handoff(options.onCreate));
    options.setupButton.addEventListener('click', () => handoff(options.onSetup));
    options.closeButton.addEventListener('click', () => {
      if (options.sheet.open) options.sheet.close();
    });
    options.eventTarget?.addEventListener('online', render);
    options.eventTarget?.addEventListener('offline', render);
  }

  globalThis.stackchainFirstTaskCompleting = () => state() === 'coaching';
  return {required, open, refresh, render, start, completeOutcome, adoptRemote};
});
