export function createSceneSystemRegistry(definitions = []) {
  const systems = new Map();

  for (const definition of definitions) {
    if (!definition?.key || typeof definition.create !== 'function') {
      throw new TypeError('Scene system definitions require a key and create function');
    }
    if (systems.has(definition.key)) {
      throw new Error(`Duplicate scene system key: ${definition.key}`);
    }
    systems.set(definition.key, {
      resultKey: definition.resultKey || definition.key,
      ...definition,
    });
  }

  function createEnabled(sceneData, context = {}, onError = () => {}) {
    const instances = {};
    for (const definition of systems.values()) {
      const config = sceneData?.[definition.key];
      if (!config?.enabled) {
        instances[definition.resultKey] = null;
        continue;
      }
      try {
        instances[definition.resultKey] = definition.create(config, context);
      } catch (error) {
        instances[definition.resultKey] = null;
        onError(definition.key, error);
      }
    }
    return instances;
  }

  function animate(key, instance, time, context = {}) {
    const definition = systems.get(key);
    if (instance && definition?.animate) definition.animate(instance, time, context);
  }

  function dispose(key, instance, context = {}) {
    const definition = systems.get(key);
    if (instance && definition?.dispose) definition.dispose(instance, context);
  }

  function animateEnabled(instances, time, context = {}) {
    for (const definition of systems.values()) {
      animate(definition.key, instances?.[definition.resultKey], time, context);
    }
  }

  function disposeEnabled(instances, context = {}) {
    for (const definition of systems.values()) {
      dispose(definition.key, instances?.[definition.resultKey], context);
    }
  }

  return {
    keys: () => [...systems.keys()],
    createEnabled,
    animate,
    animateEnabled,
    dispose,
    disposeEnabled,
  };
}
