

type DocumentActionsConfig = {
  instance?: any;
  addObject?: (...args: any[]) => any;
  updateObject?: (...args: any[]) => any;
  removeObject?: (...args: any[]) => any;
  readDocumentSnapshot?: (...args: any[]) => any;
  loadDocumentSnapshot?: (...args: any[]) => any;
  rebuildViewFromDocumentState?: (...args: any[]) => any;
  rebuildActiveViewFromDocument?: (...args: any[]) => any;
  syncDocumentObjectsForView?: (...args: any[]) => any;
};

export const createDocumentActions = (configOrInstance: any) => {
  const cfg: DocumentActionsConfig = (configOrInstance && (configOrInstance.instance || configOrInstance.addObject || configOrInstance.readDocumentSnapshot || configOrInstance.rebuildViewFromDocumentState))
    ? configOrInstance
    : { instance: configOrInstance };

  const instance = cfg.instance;
  const addObject = cfg.addObject ?? ((...args: any[]) => instance?.addObject?.(...args));
  const updateObject = cfg.updateObject ?? ((...args: any[]) => instance?.updateObject?.(...args));
  const removeObject = cfg.removeObject ?? ((...args: any[]) => instance?.removeObject?.(...args));
  const readDocumentSnapshot = cfg.readDocumentSnapshot ?? (() => instance?.exportSnapshot?.());
  const loadDocumentSnapshot = cfg.loadDocumentSnapshot ?? ((...args: any[]) => instance?.importSnapshot?.(...args));
  const rebuildViewFromDocumentState = cfg.rebuildViewFromDocumentState
    ?? cfg.rebuildActiveViewFromDocument
    ?? ((...args: any[]) => instance?.util?.state?.rebuildActiveViewFromDocument?.(...args));
  const syncDocumentObjectsForView = cfg.syncDocumentObjectsForView ?? (() => undefined);

  return {
    addObject,
    updateObject,
    removeObject,
    readDocumentSnapshot,
    loadDocumentSnapshot,
    rebuildViewFromDocumentState,
    rebuildActiveViewFromDocument: rebuildViewFromDocumentState,
    syncDocumentObjectsForView,
  };
};
