function createTodaySync({ storage, getLogin, fetchJson, onRemoteIds, onRemotePlan, onStatus, createOperationId, createChannel, coordinator,
  setTimer = globalThis.setTimeout, clearTimer = globalThis.clearTimeout, retryBaseMs = 1000, retryMaxMs = 30000,
  now = Date.now, maxOfflineMs = 30 * 24 * 60 * 60 * 1000 }) {
  const prefix = 'stackchain.today-sync.v1.';
  const migrationPrefix = 'stackchain.today-sync-migrated.v1.';
  const snapshotPrefix = 'stackchain.today-sync-snapshot.v1.';
  let flushing = null;
  let channel = null;
  let channelKey = '';
  let retryTimer = null;
  let retryAttempt = 0;
  let expiredCount = 0;
  let discardedCount = 0;
  let recoveryNotice = { discarded: 0, until: 0 };
  const knownOperationKeys = new Set();

  function cancelRetry() {
    if (retryTimer !== null) clearTimer?.(retryTimer);
    retryTimer = null;
  }

  function scheduleRetry(error, ownerKey) {
    if (retryTimer !== null || !pending().length || !ownerKey) return;
    const advised = Number(error?.retryAfter);
    const delayMs = Number.isFinite(advised) && advised >= 0
      ? advised * 1000
      : Math.min(retryMaxMs, retryBaseMs * (2 ** retryAttempt));
    retryAttempt += 1;
    onStatus?.('retrying', { delayMs });
    retryTimer = setTimer?.(async () => {
      retryTimer = null;
      if (key() !== ownerKey) return false;
      return flush();
    }, delayMs);
    retryTimer?.unref?.();
  }

  function key() {
    const login = String(getLogin?.() || '').trim().toLowerCase();
    return login ? prefix + encodeURIComponent(login) : '';
  }

  function snapshotKey() {
    const storageKey = key();
    return storageKey ? snapshotPrefix + storageKey.slice(prefix.length) : '';
  }

  function savedRevision() {
    try {
      const snapshot = JSON.parse(storage?.getItem(snapshotKey()) || 'null');
      return Number.isInteger(snapshot?.revision) ? snapshot.revision : -1;
    } catch (_error) {
      return -1;
    }
  }

  function adopt(plan, broadcast = true) {
    if (!Number.isInteger(plan?.revision) || !Array.isArray(plan?.ids)) return false;
    if (plan.revision < savedRevision()) return false;
    const snapshot = {
      revision: plan.revision, ids: plan.ids,
      capacity_minutes: plan.capacity_minutes ?? null, estimates: plan.estimates || {},
    };
    if (['coaching', 'complete'].includes(plan.first_task_state)) {
      snapshot.first_task_state = plan.first_task_state;
    }
    if (plan.plan_date) {
      snapshot.plan_date = plan.plan_date;
      snapshot.timezone = plan.timezone || null;
    }
    try {
      storage?.setItem(snapshotKey(), JSON.stringify(snapshot));
      const login = String(getLogin?.() || '').trim().toLowerCase();
      const activationKey = login && 'stackchain.first-task.v1:' + login;
      const current = activationKey && storage?.getItem(activationKey);
      const rank = {'': 0, coaching: 1, complete: 2};
      if (activationKey && rank[snapshot.first_task_state] > (rank[current] || 0)) {
        storage?.setItem(activationKey, snapshot.first_task_state);
      }
    } catch (_error) {
      // A storage quota failure must not prevent the current tab from using server truth.
    }
    onRemoteIds?.(plan.ids);
    onRemotePlan?.(plan);
    if (broadcast) channel?.postMessage(snapshot);
    return true;
  }

  function ensureChannel() {
    const storageKey = key();
    if (!storageKey || channelKey === storageKey) return;
    channel?.close?.();
    const factory = createChannel || (globalThis.window?.BroadcastChannel
      ? name => new globalThis.window.BroadcastChannel(name)
      : null);
    channelKey = storageKey;
    channel = factory?.('stackchain-today-' + storageKey.slice(prefix.length)) || null;
    channel?.addEventListener?.('message', event => {
      if (key() === storageKey) adopt(event.data, false);
    });
  }

  function pending() {
    const storageKey = key();
    if (!storageKey || !storage) return [];
    const recordPrefix = storageKey + '.operation.';
    try {
      const legacy = JSON.parse(storage.getItem(storageKey) || '[]');
      if (Array.isArray(legacy)) {
        legacy.forEach((operation, index) => {
          if (!operation?.operation_id) return;
          const recordKey = recordPrefix + encodeURIComponent(operation.operation_id);
          storage.setItem(recordKey, JSON.stringify({ operation, queued_at: index }));
          knownOperationKeys.add(recordKey);
        });
        if (legacy.length) storage.removeItem(storageKey);
      }
      const keys = new Set([...knownOperationKeys].filter(candidate => candidate.startsWith(recordPrefix)));
      for (let index = 0; index < Number(storage.length || 0); index += 1) {
        const candidate = storage.key?.(index);
        if (candidate?.startsWith(recordPrefix)) keys.add(candidate);
      }
      const records = [];
      for (const recordKey of keys) {
        let record;
        try {
          record = JSON.parse(storage.getItem(recordKey) || 'null');
        } catch (_error) {
          storage.removeItem(recordKey);
          knownOperationKeys.delete(recordKey);
          discardedCount += 1;
          continue;
        }
        const operations = Array.isArray(record?.operations) ? record.operations : [record?.operation];
        const valid = operations.length && operations.every(operation => operation &&
          typeof operation.operation_id === 'string' &&
          ['add', 'remove', 'move', 'configure', 'rollover', 'activate'].includes(operation.action) &&
          typeof operation.item_id === 'string') && Number.isFinite(Number(record.queued_at));
        if (valid) operations.forEach((operation, index) => {
          records.push({operation, queued_at:Number(record.queued_at) + index / 1000, recordKey});
        });
        else {
          storage.removeItem(recordKey);
          knownOperationKeys.delete(recordKey);
          discardedCount += 1;
        }
      }
      const expired = records.filter(record => Number(record.queued_at) >= 1_000_000_000_000 &&
        now() - Number(record.queued_at) > maxOfflineMs);
      expired.forEach(record => {
        storage.removeItem(record.recordKey);
        knownOperationKeys.delete(record.recordKey);
      });
      if (expired.length) {
        expiredCount += expired.length;
        onStatus?.('expired', { count: expiredCount });
      }
      return records.filter(record => !expired.includes(record))
        .sort((left, right) => Number(left.queued_at || 0) - Number(right.queued_at || 0) ||
          left.operation.operation_id.localeCompare(right.operation.operation_id))
        .map(record => ({
          ...record.operation,
          base_revision: Number.isInteger(record.operation.base_revision)
            ? record.operation.base_revision : Math.max(0, savedRevision()),
        }))
        .filter(operation => operation && typeof operation.operation_id === 'string' &&
          ['add', 'remove', 'move', 'configure', 'rollover', 'activate'].includes(operation.action) && typeof operation.item_id === 'string');
    } catch (_error) {
      return [];
    }
  }

  function removeOperation(operationId) {
    const storageKey = key();
    if (!storageKey || !storage) return false;
    const recordKey = storageKey + '.operation.' + encodeURIComponent(operationId);
    try {
      storage.removeItem(recordKey);
      knownOperationKeys.delete(recordKey);
      return true;
    } catch (_error) {
      return false;
    }
  }

  function operationId() {
    if (createOperationId) return createOperationId();
    if (globalThis.crypto?.randomUUID) return globalThis.crypto.randomUUID();
    return Date.now().toString(36) + '-' + Math.random().toString(36).slice(2);
  }

  function saveOperations(operations, queuedAt = now()) {
    const storageKey = key();
    if (!storageKey || !storage) return false;
    const batched = operations.length > 1;
    const recordKey = storageKey + '.operation.' + encodeURIComponent(operations[0].operation_id);
    try {
      storage.setItem(recordKey, JSON.stringify(batched ?
        {operations, queued_at:queuedAt} : {operation:operations[0], queued_at:queuedAt}));
      knownOperationKeys.add(recordKey);
      coordinator?.notify('today');
      onStatus?.('pending');
      return true;
    } catch (_error) {
      onStatus?.('error');
      return false;
    }
  }

  function enqueue(action, itemId, direction = null, fields = {}) {
    const operations = pending();
    if (action === 'remove' && operations.some(operation =>
      operation.action === 'remove' && operation.item_id === itemId
    )) {
      onStatus?.('pending');
      return true;
    }
    const operation = {
      operation_id: operationId(), action, item_id: itemId, direction,
      base_revision: Math.max(0, savedRevision()), ...fields,
    };
    return saveOperations([operation], now() + operations.length);
  }

  function enqueueBatch(specifications) {
    const operations = specifications.map(specification => ({
      operation_id: operationId(), direction: specification.direction ?? null,
      base_revision: Math.max(0, savedRevision()), ...specification,
    }));
    return saveOperations(operations);
  }

  function enqueueConfiguration(capacityMinutes, estimates) {
    const operation = {
      operation_id: operationId(), action: 'configure', item_id: 'plan', direction: null,
      capacity_minutes: capacityMinutes, estimates: estimates || {},
      base_revision: Math.max(0, savedRevision()),
    };
    const storageKey = key();
    if (!storageKey || !storage) return false;
    const recordKey = storageKey + '.operation.' + encodeURIComponent(operation.operation_id);
    try {
      storage.setItem(recordKey, JSON.stringify({ operation, queued_at: now() }));
      knownOperationKeys.add(recordKey);
      coordinator?.notify('today');
      onStatus?.('pending');
      return true;
    } catch (_error) {
      onStatus?.('error');
      return false;
    }
  }

  function enqueueActivation(state) {
    if (!['coaching', 'complete'].includes(state)) return false;
    const rank = {coaching: 1, complete: 2};
    const queued = pending().filter(operation => operation.action === 'activate');
    if (queued.some(operation => rank[operation.activation_state] >= rank[state])) return true;
    queued.forEach(operation => removeOperation(operation.operation_id));
    return enqueue('activate', 'first-task', null, {activation_state: state});
  }

  function enqueueRollover(proposed) {
    if (!proposed || proposed.action !== 'rollover') return false;
    const operation = {
      ...proposed, operation_id: operationId(), base_revision: Math.max(0, savedRevision()),
    };
    const storageKey = key();
    if (!storageKey || !storage) return false;
    const recordKey = storageKey + '.operation.' + encodeURIComponent(operation.operation_id);
    try {
      storage.setItem(recordKey, JSON.stringify({ operation, queued_at: now() }));
      knownOperationKeys.add(recordKey);
      coordinator?.notify('today');
      onStatus?.('pending');
      return true;
    } catch (_error) {
      onStatus?.('error');
      return false;
    }
  }

  function migrate(ids) {
    const storageKey = key();
    if (!storageKey || !storage) return false;
    const marker = migrationPrefix + storageKey.slice(prefix.length);
    try {
      if (storage.getItem(marker)) return false;
      for (const id of ids || []) enqueue('add', id);
      storage.setItem(marker, '1');
      return true;
    } catch (_error) {
      return false;
    }
  }

  async function run() {
    const ownerKey = key();
    if (!ownerKey) return false;
    ensureChannel();
    expiredCount = 0;
    try {
      let operations = pending();
      let plan;
      let hadConflict = false;
      if (!operations.length) {
        plan = await fetchJson('api/v1/today');
        operations = pending();
      }
      while (operations.length) {
        if (key() !== ownerKey) return false;
        const batch = operations.slice(0, 50);
        plan = await fetchJson('api/v1/today', {
          method: 'PATCH',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ operations: batch }),
        });
        const hasReceipts = Array.isArray(plan.accepted_operation_ids) ||
          Array.isArray(plan.duplicate_operation_ids) || Array.isArray(plan.rejected_operations);
        const received = hasReceipts ? [
          ...(plan.accepted_operation_ids || []),
          ...(plan.duplicate_operation_ids || []),
          ...(plan.rejected_operations || []).map(item => item.operation_id),
        ] : batch.map(item => item.operation_id);
        hadConflict = hadConflict || Boolean(plan.rejected_operations?.length);
        for (const operationId of received) {
          if (pending().some(candidate => candidate.operation_id === operationId) &&
              !removeOperation(operationId)) {
            throw new Error('Could not persist Today delivery receipt');
          }
        }
        operations = pending();
      }
      adopt(plan);
      const stillPending = pending().length;
      if (discardedCount) recoveryNotice = { discarded: discardedCount, until: now() + 5000 };
      const recovered = recoveryNotice.until > now() ? recoveryNotice.discarded : 0;
      onStatus?.(stillPending ? 'pending' : hadConflict ? 'full' :
        expiredCount ? 'expired' : recovered ? 'recovered' : 'saved',
      expiredCount ? { count: expiredCount } : recovered ? { discarded: recovered } : {});
      if (!stillPending) discardedCount = 0;
      retryAttempt = 0;
      cancelRetry();
      return !hadConflict;
    } catch (error) {
      const stillPending = pending().length;
      if (discardedCount) recoveryNotice = { discarded: discardedCount, until: now() + 5000 };
      const recovered = recoveryNotice.until > now() ? recoveryNotice.discarded : 0;
      if (stillPending) scheduleRetry(error, ownerKey);
      else onStatus?.(recovered ? 'recovered' : 'error', recovered ? { discarded: recovered } : {});
      discardedCount = 0;
      return false;
    }
  }

  function flush() {
    if (!flushing) {
      const delivery = coordinator ? coordinator.runExclusive('today', run) : run();
      flushing = Promise.resolve(delivery).finally(() => { flushing = null; });
    }
    return flushing;
  }

  function startLifecycle({ window: windowObject, document: documentObject }) {
    windowObject?.addEventListener?.('online', flush);
    windowObject?.addEventListener?.('stackchain:first-task-complete', () => {
      if (enqueueActivation('complete')) flush();
    });
    documentObject?.addEventListener?.('visibilitychange', () =>
      documentObject.hidden ? false : flush()
    );
  }

  coordinator?.subscribe(change => {
    if (change.queue === 'today' && pending().length) flush();
  });

  return { enqueue, enqueueBatch, enqueueConfiguration, enqueueActivation, enqueueRollover, migrate, flush, pending, startLifecycle };
}

if (typeof module !== 'undefined' && module.exports) module.exports = createTodaySync;
