function createUpdateReplyReadNext({
  post, markRead, queue, canQueue, deliver, accept = () => undefined, next = () => undefined,
}) {
  let inFlight = null;

  async function admit(item, body, operationId, replyConfirmed) {
    const admission = await queue({
      kind: 'update-reply-read',
      notificationId: item.notification_id,
      body,
      operationId,
      replyConfirmed,
    });
    if (!admission || (!admission.item && admission.durable !== true)) {
      throw new Error('Reply and acknowledgement were not saved for delivery.');
    }
    accept(item);
    return {
      accepted: true,
      delivery: admission.background ? 'queued' : 'saved',
      next: await next(item),
    };
  }

  function submit(item, body, operationId, attachment = null) {
    if (inFlight) return inFlight;
    inFlight = (async () => {
      let replyConfirmed = false;
      try {
        if (attachment) {
          const admission = await queue({
            kind:'update-reply-read', notificationId:item.notification_id, body,
            operationId, replyConfirmed:false, attachment,
          });
          if (!admission?.item) throw new Error('Reply and screenshot were not saved for delivery.');
          const outcome = deliver ? await deliver(admission.item) : null;
          const remaining = outcome?.remaining?.find(candidate => candidate.id === admission.item.id);
          if (remaining?.status === 'attention') {
            throw new Error(remaining.error || 'Reply and screenshot need attention.');
          }
          accept(item);
          return { accepted:true, delivery:outcome?.confirmed?.length ? 'posted' : 'queued', next:await next(item) };
        }
        try {
          await post(item, body, operationId);
          replyConfirmed = true;
          await markRead(item.notification_id);
        } catch (error) {
          if (!canQueue(error)) throw error;
          return await admit(item, body, operationId, replyConfirmed);
        }
        accept(item);
        return { accepted: true, delivery: 'posted', next: await next(item) };
      } finally {
        inFlight = null;
      }
    })();
    return inFlight;
  }

  return { submit, busy: () => Boolean(inFlight) };
}

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