import { useRef, useEffect } from "react";
import { useFrame } from "@react-three/fiber";
import { Stage, useGLTF } from "@react-three/drei";
import { AnimationMixer, AnimationAction, Object3D } from "three";
import * as THREE from "three";
import { fetchGltfUrl } from "../../services/marketplace/fetchGltfUrl";

interface GltfLoaderProps {
  glbdata?: boolean;
  fromServer?: string;
  setAnimations?: (animations?: string[]) => void;
  selectedAnimation?: string;
  setSelectedAnimation?: (animation: string) => void;
}

// const getGLTFUrl = (url: string) => url; // Placeholder for your actual function

const GltfLoader: React.FC<GltfLoaderProps> = ({
  glbdata,
  fromServer,
  setAnimations,
  selectedAnimation,
}) => {
  const modelUrl: any = fromServer ? fetchGltfUrl(fromServer) : glbdata;
  const { scene, animations } = useGLTF(modelUrl ?? "") as {
    scene: Object3D;
    animations: THREE.AnimationClip[];
  };

  const mixer = useRef<AnimationMixer | null>(
    scene ? new AnimationMixer(scene) : null
  );
  const actions = useRef<Record<string, AnimationAction>>({});

  useEffect(() => {
    if (animations.length > 0 && mixer.current && setAnimations) {
      const animationNames = animations.map((animation) => animation.name);
      setAnimations(animationNames);

      animations.forEach((animation) => {
        const action = mixer.current!.clipAction(animation);
        actions.current[animation.name] = action;
      });
    } else {
      setAnimations && setAnimations([]);
    }
  }, [animations, setAnimations]);

  useEffect(() => {
    if (actions.current && selectedAnimation) {
      const action = actions.current[selectedAnimation];
      if (action) {
        action.reset().fadeIn(0.5).play();
        return () => {
          action.fadeOut(0.5);
        };
      }
    }
  }, [selectedAnimation]);

  useFrame((_, delta) => {
    if (mixer.current) {
      mixer.current.update(delta);
    }
  });

  return (
    <Stage
      adjustCamera={false}
      intensity={0.5}
      shadows="contact"
      environment="city"
    >
      <primitive object={scene} scale={1} />
    </Stage>
  );
};

export default GltfLoader;
