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

function addPointToScene(
  position: Types.Vector3,
  colour: Types.Color,
  currentLayerPoint: Types.RefMeshArray,
  floorPlanGroupPoint: Types.RefGroup,
  dragPointControls: Types.RefDragControl | undefined,
  uuid: Types.RefString | undefined,
  Type: Types.String
): Types.Mesh {

  //////////  A function that creates and adds a cube (point) with an outline based on the position and colour given as params, It also updates the drag controls objects and sets the box uuid in uuid.current  //////////

  const geometry = new THREE.BoxGeometry(...CONSTANTS.pointConfig.boxScale);
  const material = new THREE.ShaderMaterial({
    uniforms: {
      uColor: { value: new THREE.Color(colour) }, // Blue color for the border
      uInnerColor: { value: new THREE.Color(CONSTANTS.pointConfig.defaultInnerColor) }, // White color for the inner square
    },
    vertexShader: `
                varying vec2 vUv;
            
                void main() {
                  vUv = uv;
                  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                }
              `,
    fragmentShader: `
                varying vec2 vUv;
                uniform vec3 uColor;
                uniform vec3 uInnerColor;
            
                void main() {
                  // Define the size of the white square as a proportion of the face
                  float borderThickness = 0.2; // Adjust this value for border thickness
                  if (vUv.x > borderThickness && vUv.x < 1.0 - borderThickness && 
                      vUv.y > borderThickness && vUv.y < 1.0 - borderThickness) {
                    gl_FragColor = vec4(uInnerColor, 1.0); // White inner square
                  } else {
                    gl_FragColor = vec4(uColor, 1.0); // Blue border
                  }
                }
              `,
  });
  const point = new THREE.Mesh(geometry, material);
  point.name = "point";
  point.userData = { type: Type, color: colour };
  point.position.set(position.x, 0.01, position.z);

  currentLayerPoint.current.push(point);
  floorPlanGroupPoint.current.add(point);
  if (uuid) {
    uuid.current = point.uuid;
  }
  if (dragPointControls) {
    dragPointControls.current!.objects = currentLayerPoint.current;
  }

  return point;
}

export default addPointToScene;
