import { Engine } from "../core/index.js";
import { Renderer } from "../rendering/index.js";
import { createAssetViewerWorkflow, createInteractiveSceneWorkflow, createMaterialStudioWorkflow, createProductConfiguratorWorkflow, createSceneShowcaseWorkflow } from "../workflows/index.js";
export const A3D_APP_WORKFLOW_PRESETS = [
    "asset-viewer",
    "product-configurator",
    "material-studio",
    "scene-showcase",
    "interactive-scene"
];
export function resolveA3DAppQualityPreset(preset = "balanced", overrides = {}) {
    const base = preset === "production"
        ? { width: 1600, height: 1000, antialias: true, preserveDrawingBuffer: true, targetFormat: "rgba16f" }
        : preset === "draft"
            ? { width: 960, height: 540, antialias: false, preserveDrawingBuffer: false, targetFormat: "rgba8" }
            : { width: 1280, height: 720, antialias: true, preserveDrawingBuffer: true, targetFormat: "rgba16f" };
    return {
        preset,
        ...base,
        width: overrides.width ?? base.width,
        height: overrides.height ?? base.height,
        diagnostics: [
            "quality-preset",
            "workflow-presets",
            "renderer-diagnostics",
            "engine-diagnostics"
        ]
    };
}
export async function createA3DApp(options = {}) {
    const quality = resolveA3DAppQualityPreset(options.quality, options);
    const engine = new Engine({ autoStart: false });
    await engine.init();
    const renderer = options.canvas
        ? await (options.rendererFactory ?? Renderer.create)({
            backend: "webgl2",
            canvas: options.canvas,
            width: quality.width,
            height: quality.height,
            antialias: quality.antialias,
            preserveDrawingBuffer: quality.preserveDrawingBuffer,
            clearColor: [0.018, 0.02, 0.024, 1]
        })
        : undefined;
    let disposed = false;
    let workflowRuns = 0;
    let lastWorkflow;
    let lastRender;
    return {
        engine,
        renderer,
        quality,
        async renderWorkflow(preset, workflowOptions) {
            if (disposed)
                throw new Error("A3D app has been disposed.");
            const workflow = await createWorkflow(preset, workflowOptions);
            workflowRuns += 1;
            lastWorkflow = preset;
            engine.diagnostics.increment(`workflow.${preset}.runs`);
            if (renderer) {
                lastRender = renderer.render(workflow.source, workflow.camera);
                engine.diagnostics.gauge("renderer.drawCalls", lastRender.drawCalls);
            }
            return workflow;
        },
        diagnostics() {
            return {
                appState: disposed ? "disposed" : "ready",
                quality,
                workflowRuns,
                ...(lastWorkflow ? { lastWorkflow } : {}),
                ...(lastRender ? { lastRender } : {}),
                engine: engine.diagnostics.snapshot()
            };
        },
        async dispose() {
            if (disposed)
                return;
            disposed = true;
            renderer?.dispose?.();
            await engine.dispose();
        }
    };
}
async function createWorkflow(preset, options) {
    switch (preset) {
        case "asset-viewer":
            return createAssetViewerWorkflow(options);
        case "product-configurator":
            return createProductConfiguratorWorkflow(options);
        case "material-studio":
            return createMaterialStudioWorkflow(options);
        case "scene-showcase":
            return createSceneShowcaseWorkflow(options);
        case "interactive-scene":
            return createInteractiveSceneWorkflow(options);
    }
}
//# sourceMappingURL=index.js.map