import { EngineHarness } from "../../engine/EngineHarness.js";
import { GridCellActionPlaceMarker } from "./GridCellActionPlaceMarker.js";
import { GridData } from "../grid/GridData.js";
import Entity from "../../engine/ecs/Entity.js";
import Mesh from "../../engine/graphics/ecs/mesh/Mesh.js";
import { MeshSystem } from "../../engine/graphics/ecs/mesh/MeshSystem.js";
import { GameAssetType } from "../../engine/asset/GameAssetType.js";
import { GLTFAssetLoader } from "../../engine/asset/loaders/GLTFAssetLoader.js";
import {
    AmbientOcclusionPostProcessEffect
} from "../../engine/graphics/render/buffer/simple-fx/ao/AmbientOcclusionPostProcessEffect.js";
import { MarkerNodeEmitterFromAction } from "./emitter/MarkerNodeEmitterFromAction.js";
import { Transform } from "../../engine/ecs/transform/Transform.js";
import { MarkerNodeTransformerOffsetPosition } from "./transform/MarkerNodeTransformerOffsetPosition.js";
import { MarkerNodeConsumerBuffer } from "./emitter/MarkerNodeConsumerBuffer.js";
import { normalize_angle_rad } from "../../core/geom/normalize_angle_rad.js";

const harness = new EngineHarness();

const corner = MarkerNodeEmitterFromAction.from([
    GridCellActionPlaceMarker.from({
        type: 'Construction-Corner-L',
        size: 0.2,
        tags: ['wall-segment-damaged'],
        transform: Transform.fromJSON({
            scale: 0.1
        })
    }),
    GridCellActionPlaceMarker.from({
        type: 'Virtual',
        size: 0.1,
        transform: Transform.fromJSON({
            scale: 0.1
        }),
        transformers: [
            MarkerNodeTransformerOffsetPosition.from(-0.2, 0)
        ]
    }),
    GridCellActionPlaceMarker.from({
        type: 'Virtual',
        size: 0.1,
        transform: Transform.fromJSON({
            scale: 0.1
        }),
        transformers: [
            MarkerNodeTransformerOffsetPosition.from(-0.4, 0)
        ]
    }),
    GridCellActionPlaceMarker.from({
        type: 'Virtual',
        size: 0.1,
        transform: Transform.fromJSON({
            scale: 0.1
        }),
        transformers: [
            MarkerNodeTransformerOffsetPosition.from(-0.6, 0)
        ]
    }),
    GridCellActionPlaceMarker.from({
        type: 'Virtual',
        size: 0.13,
        transform: Transform.fromJSON({
            scale: 0.1
        }),
        tags: ['wall-segment-end'],
        transformers: [
            MarkerNodeTransformerOffsetPosition.from(-0.83, 0)
        ]
    }),

    //wall 2
    GridCellActionPlaceMarker.from({
        type: 'Virtual',
        size: 0.1,
        transform: Transform.fromJSON({
            scale: 0.1
        }),
        transformers: [
            MarkerNodeTransformerOffsetPosition.from(0, -0.2)
        ]
    }),
    GridCellActionPlaceMarker.from({
        type: 'Virtual',
        size: 0.1,
        transform: Transform.fromJSON({
            scale: 0.1
        }),
        transformers: [
            MarkerNodeTransformerOffsetPosition.from(0, -0.4)
        ]
    }),
    GridCellActionPlaceMarker.from({
        type: 'Virtual',
        size: 0.1,
        transform: Transform.fromJSON({
            scale: 0.1
        }),
        transformers: [
            MarkerNodeTransformerOffsetPosition.from(0, -0.6)
        ]
    }),
    GridCellActionPlaceMarker.from({
        type: 'Virtual',
        size: 0.13,
        tags: ['wall-segment-end'],
        transform: Transform.fromJSON({
            scale: 0.1
        }),
        transformers: [
            MarkerNodeTransformerOffsetPosition.from(0, -0.83)
        ]
    })
]);

/**
 *
 * @param {Engine} engine
 */
async function main(engine) {
    EngineHarness.buildBasics({
        engine
    });

    const action = GridCellActionPlaceMarker.from({
        type: 'X',
        size: 1
    });

    const grid = new GridData();

    grid.resize(50, 50);

    corner.initialize(grid, 0);

    const GRID_CENTER_X = 12;
    const GRID_CENTER_Y = 12;

    const GRID_SIZE = 0;
    const ANGLE_STEP = Math.PI * 2 / (GRID_SIZE * GRID_SIZE);
    const GRID_SPACING = 4;

    const buffer = new MarkerNodeConsumerBuffer();

    for (let i = 0; i < GRID_SIZE * GRID_SIZE; i++) {
        const angle = i * ANGLE_STEP;

        const x = i % GRID_SIZE;

        const y = Math.floor(i / GRID_SIZE);

        const _x = GRID_CENTER_X - (GRID_SPACING * GRID_SIZE) * 0.5 + x * GRID_SPACING;
        const _y = GRID_CENTER_Y - (GRID_SPACING * GRID_SIZE) * 0.5 + y * GRID_SPACING;

        corner.execute(grid, _x, _y, angle, buffer);

        // const node = action.buildNode(grid, _x, _y, angle);

    }


    corner.execute(grid, 12, 12, (Math.PI / 2) * 0, buffer);
    corner.execute(grid, 14, 12, (Math.PI / 2) * 1, buffer);
    corner.execute(grid, 16, 12, (Math.PI / 2) * 2, buffer);
    corner.execute(grid, 18, 12, normalize_angle_rad((Math.PI / 2) * 3), buffer);


    function build_node(node, url) {

        new Entity()
            .add(node.transform)
            .add(Mesh.fromJSON({

                url: url
            }))
            .build(engine.entityManager.dataset);
    }

    console.warn(buffer);

    for (let i = 0; i < buffer.size(); i++) {
        const node = buffer.get(i);

        node.transform.position.set(
            node.position.x * grid.transform.scale_x + grid.transform.offset_x,
            node.transform.position.y,
            node.position.y * grid.transform.scale_y + grid.transform.offset_y
        );


// url: "data/models/arrow-symbols/arrow4/model.gltf"

        build_node(node, 'data/models/arrow-symbols/arrow4/model.gltf');

    }
}

harness
    .initialize({
        configuration(config, engine) {
            config.addSystem(new MeshSystem(engine));
            config.addPlugin(AmbientOcclusionPostProcessEffect);

            const gltfAssetLoader = new GLTFAssetLoader();

            config.addLoader(GameAssetType.ModelGLTF, gltfAssetLoader);
            config.addLoader(GameAssetType.ModelGLTF_JSON, gltfAssetLoader);
        }
    })
    .then(main);
