function App() {
  // const [dpr, setDpr] = useState(1.5);
  const { moveAnimation } = useSnapshot(store);
  const [isDragging, setIsDragging] = useState(false);
  const [lastX, setLastX] = useState(0);
  const [targetRotationY, setTargetRotationY] = useState(Math.PI * 0.5);
  const cameraRef = useRef(null);
  const fakeLoaderRef = useRef<HTMLDivElement>(null);

  // POINTER EVENT BOTH USE IN MOUSE AND TOUCH CONTROLS

  const handlePointerDown = (clientX: number) => {
    setIsDragging(true);
    setLastX(clientX);
  };

  const handlePointerUp = () => {
    setIsDragging(false);
  };

  const handlePointerMove = (clientX: number) => {
    if (!isDragging) return;

    const deltaX = clientX - lastX;
    setLastX(clientX);

    const rotationSpeed = 0.002;
    setTargetRotationY((prev) => prev - deltaX * rotationSpeed);
  };

  // MOUSE CONTROLS

  const handleMouseDown = (
    event: React.MouseEvent<HTMLDivElement, MouseEvent>
  ) => {
    handlePointerDown(event.clientX);
  };

  const handleMouseUp = () => {
    handlePointerUp();
  };

  const handleMouseMove = (
    event: React.MouseEvent<HTMLDivElement, MouseEvent>
  ) => {
    handlePointerMove(event.clientX);
  };

  // TOUCH CONTROLS

  const handleTouchStart = (event: React.TouchEvent<HTMLDivElement>) => {
    if (event.touches.length === 1) {
      handlePointerDown(event.touches[0].clientX);
    }
  };

  const handleTouchMove = (event: React.TouchEvent<HTMLDivElement>) => {
    if (event.touches.length === 1) {
      handlePointerMove(event.touches[0].clientX);
    }
  };

  const handleTouchEnd = () => {
    handlePointerUp();
  };

  return (
    <main>
      <div ref={fakeLoaderRef} className="fake-loader">
        <FakeLoader />
      </div>
      <div className="buttonBox">
        <button onClick={() => moveAnimation(24.2, 0, 1, 1, 1.6)}>
          Eingang / Foyer
        </button>
        <button onClick={() => moveAnimation(2.2, 14.2, 5, 3.3, 2.04)}>
          Kunststofftechnik
        </button>
        <button onClick={() => moveAnimation(0.1, 1.7, 3, 1.7, Math.PI * 0.4)}>
          Fertigung
        </button>
        <button onClick={() => moveAnimation(2.8, -12.8, 4, 2.6, 0.84)}>
          Maschinenbau
        </button>
        <button onClick={() => moveAnimation(19, 0.7, 1, 4, -0.36)}>
          Verwaltung & GF
        </button>
      </div>
      <Canvas
     
        onMouseMove={handleMouseMove}
        onMouseDown={handleMouseDown}
        onMouseUp={handleMouseUp}
        onTouchStart={handleTouchStart}
        onTouchMove={handleTouchMove}
        onTouchEnd={handleTouchEnd}
      >
        <AdaptiveDpr />
       
        <Environment preset="city" />
        <OrbitCamera
          cameraRef={cameraRef}
          setTargetRotationY={setTargetRotationY}
          targetRotationY={targetRotationY}
          fakeLoaderRef={fakeLoaderRef}
        />
        <group position={[-140, 0, 160]}>
          <Suspense fallback={null}>
            <ConditionalRender />
            <Hauptgebaeude />
            <Walls />
            <Doors />
            <Spawnpoint />
            <Labels />
          </Suspense>
        </group>
      </Canvas>
      <Loader />
    </main>
  );
}

export default App;



const OrbitCamera = ({
  cameraRef,
  targetRotationY,
  fakeLoaderRef,
  setTargetRotationY,
}: {
  fakeLoaderRef: React.RefObject<HTMLDivElement>;
  cameraRef: React.RefObject<PC>;
  targetRotationY: number;
  setTargetRotationY: React.Dispatch<React.SetStateAction<number>>;
}) => {
  const [isMainCameraActive, setIsMainCameraActive] = useState<boolean>(false);

  const secondCameraRef = useRef<PC>(null);

  useFrame(() => {
    if (cameraRef.current) {
      // Apply easing to smoothly transition to the target rotation
      cameraRef.current.rotation.y +=
        (targetRotationY - cameraRef.current.rotation.y) * 0.1;
    }
  });

 

  const { contextSafe } = useGSAP();

  useEffect(() => {
    store.moveAnimation = contextSafe(
      (
        x: number,
        z: number,
        floor?: number,
        upper?: number,
        rotateY?: number
      ) => {
        if (floor) {
          gsap
            .timeline()
            .to(cameraRef.current!.position, {
              x,
              y: upper ? upper : 1,
              z,
              duration: 0.8,
            })
            .to(fakeLoaderRef.current, { opacity: 1 }, "<")
            .call(() => {
              if (isMainCameraActive === false) setIsMainCameraActive(true);
              store.floor = floor;
              setTargetRotationY((prev) => (rotateY ? rotateY : prev));
            })
            .to(fakeLoaderRef.current, { opacity: 0 }, ">0.4");
        } else {
          gsap.to(cameraRef.current!.position, { x, z, duration: 0.8, y: 1 });
        }
      }
    );

    store.entryAnimation = contextSafe(() => {
      gsap
        .timeline()
        .to(secondCameraRef.current!.position, {
          x: 32,
          y: 1,
          z: 0,
          duration: 3,
        })
        .to(
          secondCameraRef.current!.rotation,
          {
            x: 0,
            y: 1.5,
            z: 0,
            duration: 2,
          },
          "<"
        )
        .to(
          secondCameraRef.current!.position,
          {
            x: 24.2,
            duration: 2,
          },
          "<2.2"
        )
        .to(fakeLoaderRef.current, { opacity: 1 }, "<1")
        .call(() => {
          setIsMainCameraActive(true);
          store.floor = 1;
        })
        .to(fakeLoaderRef.current, { opacity: 0 }, ">0.5");
    });
  }, []);

  return (
    <>
      <PerspectiveCamera
        makeDefault={isMainCameraActive}
        position={[24.2, 1, 0]}
        ref={cameraRef}
      />
      <PerspectiveCamera
        position={[71.5, 33.7, 26.3]}
        rotation={[-0.08, 1.2, 0.3, "XZY"]}
        ref={secondCameraRef}
        makeDefault={!isMainCameraActive}
      />
    </>
  );
};
export default OrbitCamera;


" how to limit camera rotation on mouse move"