import * as THREE from "three";
import * as Types from "../../../../types/world/worldTypes"
import * as CONSTANTS from '../../../../types/world/worldConstants';

import updateLinesPositions from "../lines/updateLinesPositions";
import updateLines from "../lines/updateLines";
import updateDistanceText from "../lines/updateDistanceText";
import updateFloorLines from "../floors/updateFloorLines";

function DragPoint(
    event: Types.IntersectionEvent,
    floorPlanGroupPoint: Types.RefGroup,
    floorPlanGroupLine: Types.RefGroup,
    scene: THREE.Scene,
    lines: Types.RefLines,
    onlyFloorlines: Types.RefOnlyFloorLines
): void {

    //////////  Calling the line updation of the affected lines and Snapping of the point during the drag  //////////

    const snapThreshold = CONSTANTS.pointConfig.snappingThreshold;
    const DragedPoint = event.object as Types.Mesh;

    floorPlanGroupPoint.current.children.forEach((point) => {
        let canSnap =
            ((DragedPoint.userData.type === CONSTANTS.lineConfig.wallName) && (point.userData.type === CONSTANTS.lineConfig.wallName || point.userData.type === CONSTANTS.lineConfig.floorName)) ||
            ((DragedPoint.userData.type === CONSTANTS.lineConfig.floorName) && (point.userData.type === CONSTANTS.lineConfig.wallName || point.userData.type === CONSTANTS.lineConfig.floorName)) ||
            ((DragedPoint.userData.type === CONSTANTS.lineConfig.aisleName) && point.userData.type === CONSTANTS.lineConfig.aisleName);
        if (canSnap && point.uuid !== DragedPoint.uuid && point.visible) {
            const distance = DragedPoint.position.distanceTo(point.position);
            if (distance < snapThreshold) {
                DragedPoint.position.copy(point.position);
            }
        }
    });

    const affectedLines = updateLinesPositions(DragedPoint, lines);

    updateLines(floorPlanGroupLine, affectedLines);
    updateDistanceText(scene, floorPlanGroupLine, affectedLines);
    updateFloorLines(onlyFloorlines, DragedPoint);
}

export default DragPoint;