import * as THREE from 'three';
import * as CONSTANTS from '../../../../types/world/worldConstants';
import addRoofToScene from '../roofs/addRoofToScene';

import * as Types from "../../../../types/world/worldTypes";
import loadOnlyFloors from './loadOnlyFloors';
import addFloorToScene from './addFloorToScene';
import getRoomsFromLines from '../lines/getRoomsFromLines';

async function loadFloor(
    lines: Types.RefLines,
    floorGroup: Types.RefGroup,
): Promise<void> {

    if (!floorGroup.current) return;

    floorGroup.current.children = [];

    if (lines.current.length > 2) {
        const linesByLayer = lines.current.reduce((acc: { [key: number]: any[] }, pair) => {
            const layer = pair[0][2];
            if (!acc[layer]) acc[layer] = [];
            acc[layer].push(pair);
            return acc;
        }, {});

        for (const layer in linesByLayer) {
            // Only Floor Polygons
            loadOnlyFloors(floorGroup, linesByLayer, layer);

            const rooms: Types.Rooms = await getRoomsFromLines({ current: linesByLayer[layer] });

            rooms.forEach(({ coordinates: room, layer }) => {
                const userData = room.map(point => point.uuid);
                const shape = new THREE.Shape();
                shape.moveTo(room[0].position.x, room[0].position.z);
                room.forEach(point => shape.lineTo(point.position.x, point.position.z));
                shape.closePath();

                // Floor Polygons
                addFloorToScene(shape, (layer - 1) * CONSTANTS.wallConfig.height, floorGroup, userData);

                // Roof Polygons
                addRoofToScene(shape, (layer - 1) * CONSTANTS.wallConfig.height, userData, floorGroup);
            });
        }
    }
}

export default loadFloor;
