(function (root, factory) {
  const createConversationPhotoDrafts = factory();
  if (typeof module === 'object' && module.exports) module.exports = createConversationPhotoDrafts;
  else root.createConversationPhotoDrafts = createConversationPhotoDrafts;
})(typeof globalThis !== 'undefined' ? globalThis : this, function () {
  'use strict';

  return function createConversationPhotoDrafts({ store, lanes }) {
    const states = {};
    Object.entries(lanes || {}).forEach(([kind, lane]) => {
      states[kind] = { ...lane, target:null, generation:0, restoring:false, pending:Promise.resolve() };
    });

    function state(kind) {
      const value = states[kind];
      if (!value) throw new Error('Unknown conversation photo draft lane.');
      return value;
    }

    async function checkpoint(kind) {
      const current = state(kind);
      if (!current.target || current.restoring) return null;
      const target = { ...current.target };
      const attachments = await current.controller.serialize();
      const save = current.pending.then(() => store.save(target, attachments));
      current.pending = save.catch(() => null);
      try { return await save; }
      catch (error) { current.onError?.(error); throw error; }
    }

    async function open(kind, target) {
      const current = state(kind);
      const generation = ++current.generation;
      current.target = { ...target };
      await current.pending;
      const attachments = await store.load(target);
      if (generation !== current.generation) return false;
      current.restoring = true;
      try {
        current.controller.clear();
        if (attachments?.length) current.controller.restore(attachments);
      } finally { current.restoring = false; }
      return Boolean(attachments?.length);
    }

    async function leave(kind) {
      const current = state(kind);
      const generation = current.generation;
      if (!current.target) return true;
      try { await checkpoint(kind); }
      catch (_error) { return false; }
      if (generation === current.generation) {
        current.restoring = true;
        try { current.controller.clear(); }
        finally {
          current.restoring = false;
          current.target = null;
          current.generation += 1;
        }
      }
      return true;
    }

    async function complete(kind) {
      const current = state(kind);
      if (!current.target) return false;
      const target = { ...current.target };
      await current.pending;
      await store.remove(target);
      current.restoring = true;
      try { current.controller.clear(); }
      finally {
        current.restoring = false;
        current.target = null;
        current.generation += 1;
      }
      return true;
    }

    async function switchTo(kind, target, isCurrent = () => true) {
      if (!await leave(kind) || !isCurrent()) return false;
      return open(kind, target);
    }

    function hasTarget(kind) { return Boolean(state(kind).target); }
    return { checkpoint, open, switchTo, leave, complete, hasTarget };
  };
});
