import { initAnimationAutoplay } from "../engine-components/AnimationUtilsAutoplay.js";
import { initCameraUtils } from "../engine-components/CameraUtils.js";
import { initSceneSwitcherAttributes } from "../engine-components/SceneSwitcher.js";
import { initSkyboxAttributes } from "../engine-components/Skybox.js";
import { initBuiltinTypes } from "./codegen/register_types.js";
import { ensureAudioContextIsResumed } from "./engine_audio.js";
import { initNeedleLoader } from "./engine_loaders.js";
import { initShims } from "./engine_shims.js";
import { patchTonemapping } from "./engine_tonemapping.js";
import { initCameraExtensions } from "./js-extensions/Camera.js";
import { patchLayers } from "./js-extensions/Layers.js";
import { initObject3DExtensions } from "./js-extensions/Object3D.js";
import { initVectorExtensions } from "./js-extensions/Vector.js";
import { initWebComponents } from "./webcomponents/init.js";

let initialized = false;

/**
 * Initialize all engine subsystems. Called once from the entry point.
 *
 * Every subsystem (prototype patches, type registrations, loader setup, etc.)
 * is wrapped in an explicit init function instead of running at module scope.
 * This creates an unbroken call chain from the entry point that bundlers can
 * trace, so the package can declare `sideEffects: false` and tree-shake
 * correctly — without maintaining a fragile list of side-effect files.
 */
export function initEngine() {
    if (initialized) return;
    initialized = true;

    initWebComponents();
    initShims();
    patchTonemapping();
    patchLayers();
    initCameraExtensions();
    initObject3DExtensions();
    initVectorExtensions();
    initBuiltinTypes();
    initNeedleLoader();
    setTimeout(ensureAudioContextIsResumed, 1000);
    initCameraUtils();
    initAnimationAutoplay();
    initSkyboxAttributes();
    initSceneSwitcherAttributes();
}
