import * as Types from "../../../types/world/worldTypes";
import * as  CONSTANTS from '../../../types/world/worldConstants';
import createAndMoveReferenceLine from "../geomentries/lines/createAndMoveReferenceLine";

async function Draw(
    state: Types.ThreeState,
    plane: Types.RefMesh,
    cursorPosition: Types.Vector3,
    floorPlanGroupPoint: Types.RefGroup,
    floorPlanGroupLine: Types.RefGroup,
    snappedPoint: Types.RefVector3,
    isSnapped: Types.RefBoolean,
    isSnappedUUID: Types.RefString,
    line: Types.RefLine,
    lines: Types.RefLines,
    ispreSnapped: Types.RefBoolean,
    floorPlanGroup: Types.RefGroup,
    ReferenceLineMesh: Types.RefMesh,
    LineCreated: Types.RefBoolean,
    setRefTextUpdate: any,
    Tube: Types.RefTubeGeometry,
    anglesnappedPoint: Types.RefVector3,
    isAngleSnapped: Types.RefBoolean,
    toolMode: Types.String,
): Promise<void> {

    //////////  Snapping the cursor during the drawing time and also changing the color of the intersected lines  ////////// 

    if (!plane.current) return;
    const intersects = state.raycaster.intersectObject(plane.current, true);

    if (intersects.length > 0 && (toolMode === "Wall" || toolMode === "Aisle" || toolMode === "Floor")) {
        const intersectionPoint = intersects[0].point;
        cursorPosition.copy(intersectionPoint);
        const snapThreshold = 1;

        if (line.current.length === 0) {
            for (const point of floorPlanGroupPoint.current.children) {
                const pointType = point.userData.type;

                const canSnap =
                    ((toolMode === "Wall") && (pointType === CONSTANTS.lineConfig.wallName || pointType === CONSTANTS.lineConfig.floorName)) ||
                    ((toolMode === "Floor") && (pointType === CONSTANTS.lineConfig.wallName || pointType === CONSTANTS.lineConfig.floorName)) ||
                    ((toolMode === "Aisle") && pointType === CONSTANTS.lineConfig.aisleName);;

                if (canSnap && cursorPosition.distanceTo(point.position) < snapThreshold + 0.5 && point.visible) {
                    cursorPosition.copy(point.position);
                    snappedPoint.current = point.position;
                    ispreSnapped.current = true;
                    isSnapped.current = false;
                    isSnappedUUID.current = point.uuid;
                    break;
                } else {
                    ispreSnapped.current = false;
                }
            }
        } else if (line.current.length > 0 && line.current[0]) {
            for (const point of floorPlanGroupPoint.current.children) {
                const pointType = point.userData.type;

                let canSnap =
                    ((toolMode === "Wall") && (pointType === CONSTANTS.lineConfig.wallName || pointType === CONSTANTS.lineConfig.floorName)) ||
                    ((toolMode === "Floor") && (pointType === CONSTANTS.lineConfig.wallName || pointType === CONSTANTS.lineConfig.floorName)) ||
                    ((toolMode === "Aisle") && pointType === CONSTANTS.lineConfig.aisleName);

                if (canSnap && cursorPosition.distanceTo(point.position) < snapThreshold && point.visible) {
                    cursorPosition.copy(point.position);
                    snappedPoint.current = point.position;
                    isSnapped.current = true;
                    ispreSnapped.current = false;
                    isSnappedUUID.current = point.uuid;
                    break;
                } else {
                    isSnapped.current = false;
                }
            }

            createAndMoveReferenceLine(
                line.current[0][0],
                cursorPosition,
                isSnapped,
                ispreSnapped,
                line,
                setRefTextUpdate,
                floorPlanGroup,
                ReferenceLineMesh,
                LineCreated,
                Tube,
                anglesnappedPoint,
                isAngleSnapped
            );
        }
    }

}

export default Draw;