import { EngineHarness } from "../../../../EngineHarness.js";
import { ShadedGeometrySystem } from "../ShadedGeometrySystem.js";
import { GameAssetType } from "../../../../asset/GameAssetType.js";
import { EngineConfiguration } from "../../../../EngineConfiguration.js";
import { GLTFAssetLoader } from "../../../../asset/loaders/GLTFAssetLoader.js";
import { three_object_to_entity_composition } from "../three_object_to_entity_composition.js";
import { TransformAttachmentSystem } from "../../../../ecs/transform-attachment/TransformAttachmentSystem.js";
import { Camera } from "../../camera/Camera.js";
import { enableEditor } from "../../../../../../editor/enableEditor.js";
import { MeshSystem } from "../../mesh/MeshSystem.js";

const eh = new EngineHarness();

/**
 *
 * @param {EngineHarness} harness
 * @return {Promise<void>}
 */
async function init(harness) {
    const engine = harness.engine;

    const config = new EngineConfiguration();

    config.addSystem(new ShadedGeometrySystem(engine));
    config.addSystem(new TransformAttachmentSystem());
    config.addSystem(new MeshSystem(engine));

    const gltfAssetLoader = new GLTFAssetLoader();

    config.addLoader(GameAssetType.ModelGLTF_JSON, gltfAssetLoader);
    config.addLoader(GameAssetType.ModelGLTF, gltfAssetLoader);

    await config.apply(engine);

    enableEditor(engine);

    eh.initialize().then(main);
}

/**
 *
 * @param {string} path
 * @param {Engine} engine
 */
async function load_gltf(path, engine) {
    const em = engine.entityManager;

    const ecd = em.dataset;

    const asset = await engine.assetManager.promise(path, GameAssetType.ModelGLTF_JSON);

    const three_object = asset.create();

    console.time('composition conversion');
    const composition = three_object_to_entity_composition(three_object);
    console.timeEnd('composition conversion');

    if (asset.has_root_transform) {
        composition.transform.multiplyTransforms(composition.transform, asset.root_transform);
    }

    console.time('composition build');
    // console.profile('composition build');
    composition.build(ecd);
    // console.profileEnd('composition build');
    console.timeEnd('composition build');


    // console.log(composition);
    // console.log(three_object);
    //
    // new Entity()
    //     .add(Mesh.fromJSON({
    //         url: path
    //     }))
    //     .add(Transform.fromJSON({
    //         position: {
    //             x: 5,
    //             y: 0,
    //             z: 0
    //         }
    //     }))
    //     .build(ecd);
}

async function timeout(t = 1) {
    await new Promise((resolve, reject) => setTimeout(resolve, t));
}

/**
 *
 * @param {Engine} engine
 */
async function main(engine) {

    EngineHarness.buildBasics({
        engine,
        enableWater: false,
        enableTerrain: false
    });

    const camera = engine.entityManager.dataset.getAnyComponent(Camera);
    camera.component.autoClip = false;
    camera.component.object.far = 300;

    // a small delay to let background tasks finish, so we can get better performance reading later on
    timeout(20);

    load_gltf('moicon/06_04_hapro/08-clickable-assets-new/model.gltf', engine);
    // load_gltf('moicon/06_04_hapro/07-1st-basement/model.gltf', engine);
    // load_gltf('moicon/06_04_hapro/06-lower-ground/model.gltf', engine);
    // load_gltf('moicon/06_04_hapro/05-ground-floor/model.gltf', engine);
    // load_gltf('moicon/06_04_hapro/04-1st-floor/model.gltf', engine);
    // load_gltf('moicon/06_04_hapro/03-2nd-floor/model.gltf', engine);

    // for (let i = 1; i <= 6; i++) {
    //     load_gltf(`moicon/10_Feb_22_Demo/${i}/model.gltf`, engine);
    // }
    // load_gltf(`moicon/10_Feb_22_Demo/1/model.gltf`, engine);
    // load_gltf(`moicon/10_Feb_22_Demo/2/model.gltf`, engine);
    // load_gltf(`moicon/10_Feb_22_Demo/3/model.gltf`, engine);

    // load_gltf(`data/models/samples/transform-hierarchy.glb`, engine);

}

init(eh);
