import { Debug } from '@react-three/cannon';
import { useLoader } from '@react-three/fiber'
import { useEffect, useState } from 'react';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

var treeType = {
  position: {x: Number, z: Number},
  box: Number
}


var props = {
  boundary: Number,
  count: Number
}


const Trees = ({boundary, count}) => {
  const model = useLoader(GLTFLoader, "models/tree.glb");
  
  const [trees, setTrees] = useState([]);

  model.scene.scale.set(0.02,0.02,0.02);

  model.scene.traverse((object) => {
    if(object.isMesh){
      object.castShadow = true;
    }
  });


  const boxIntersect = (
    minAx= Number,
    minAz= Number,
    maxAx= Number,
    maxAz= Number,
    minBx= Number,
    minBz= Number,
    maxBx= Number,
    maxBz= Number,
  ) => {
    let aLeftOfB = maxAx < minBx;
    let aRightOfB = minAx > maxBx;
    let aAboveB = minAz < maxBz;
    let aBelowB = maxAz < minBz;

    return !(aLeftOfB || aRightOfB || aAboveB || aBelowB);
  };



  const isOverlapping = (
    index= Number,
    tree,
    trees,
  ) => {
    const minTargetX = tree.position.x - tree.box / 2;
    const maxTargetX = tree.position.x + tree.box / 2;
    const minTargetZ = tree.position.z - tree.box / 2;
    const maxTargetZ = tree.position.z + tree.box / 2;
    for(let i = 0; i < index; i++){
      let minChildX =trees[i].position.x - trees[i].box / 2;
      let maxChildX =trees[i].position.x + trees[i].box / 2;
      let minChildZ =trees[i].position.z - trees[i].box / 2;
      let maxChildZ =trees[i].position.z + trees[i].box / 2;
  
      if(boxIntersect(minTargetX, minTargetZ, maxTargetX, maxTargetZ, minChildX, minChildZ, maxChildX, maxChildZ)){
        //console.log("overlapping", tree.position);
        return true;
      }
    }
    return false;
  }



  //funzione per calcolare una nuova posizione, boundary indica l'area dove possono essere generati
  const newPosition = (box = Number, boundary = Number) => {
    return(
      boundary / 2 - box / 2 - (boundary - box) * (Math.round(Math.random() * 100)/100)
    )
  }

  const updatePosition = (treeArray = treeType, boundary = Number) => {
    treeArray.forEach((tree, index) => {
      do{
        tree.position.x = newPosition(tree.box, boundary);
        tree.position.z = newPosition(tree.box, boundary);
      } while(isOverlapping(index, tree, treeArray));
    });
    setTrees(treeArray);
  }

  useEffect(() => {
    const tempTrees = treeType = [];
    for(let i = 0; i < count; i++){
      tempTrees.push({ position: { x: 0, z: 0}, box: 1});
    }

    updatePosition(tempTrees, boundary);
    
    //console.log(tempTrees);
  }, [boundary, count]);



  return(
          <group>
            {trees.map((tree, index) => {
              return(
                <object3D key={index} position={[tree.position.x, 0, tree.position.z]}>
                  <mesh scale={[tree.box, tree.box, tree.box]}>
                    <boxGeometry />
                    <meshBasicMaterial color = {"blue"} wireframe />
                  </mesh>
                  <primitive object={model.scene.clone()} />
                </object3D>
              );
            })}
          </group>
        );
};

export default Trees;