function createWorkSelection({ limit = 50, onChange = () => {} } = {}) {
  const maximum = Number.isInteger(limit) && limit > 0 ? limit : 50;
  let active = false;
  const selected = new Set();

  function identity(item) {
    if (!item) return '';
    const kind = item.is_review ? 'review' : (item.kind || 'work');
    const number = Number.isInteger(item.number) ? item.number : '';
    const notification = Number.isInteger(item.notification_id) ? item.notification_id : '';
    return [kind, item.repository || '', number, notification].join(':');
  }

  function changed() {
    const state = snapshot();
    onChange(state);
    return state;
  }

  function start() {
    active = true;
    selected.clear();
    return changed();
  }

  function cancel() {
    active = false;
    selected.clear();
    return changed();
  }

  function select(item) {
    if (!active) return 'inactive';
    const id = identity(item);
    if (!id) return 'invalid';
    if (selected.has(id)) return 'selected';
    if (selected.size >= maximum) return 'limit';
    selected.add(id);
    changed();
    return 'selected';
  }

  function toggle(item) {
    if (!active) return 'inactive';
    const id = identity(item);
    if (!id) return 'invalid';
    if (selected.has(id)) {
      selected.delete(id);
      changed();
      return 'removed';
    }
    return select(item);
  }

  function selectMany(items) {
    if (!active) return { status: 'inactive', added: 0, count: selected.size, limit: maximum };
    let added = 0;
    let capped = false;
    for (const item of items || []) {
      const id = identity(item);
      if (!id || selected.has(id)) continue;
      if (selected.size >= maximum) {
        capped = true;
        break;
      }
      selected.add(id);
      added += 1;
    }
    changed();
    return { status: capped ? 'limit' : 'selected', added, count: selected.size, limit: maximum };
  }

  function clear() {
    if (!active) return snapshot();
    selected.clear();
    return changed();
  }

  function retain(items) {
    const retained = new Set((items || []).map(identity).filter(Boolean));
    Array.from(selected).forEach(id => { if (!retained.has(id)) selected.delete(id); });
    return changed();
  }

  function snapshot() {
    return { active, count: selected.size, ids: Array.from(selected) };
  }

  return { identity, start, cancel, select, selectMany, clear, toggle, retain, snapshot, limit: maximum };
}

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