import * as THREE from 'three'
import React, { useState, useEffect, useRef } from 'react';
import { OrbitControls } from '@react-three/drei'
import { useFrame, Canvas } from '@react-three/fiber';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { VRM, VRMUtils, VRMLoaderPlugin } from '@pixiv/three-vrm';
import { VRMAnimationLoaderPlugin, VRMAnimation, createVRMAnimationClip } from "@pixiv/three-vrm-animation";
import { VRMSpringBoneManager } from '@pixiv/three-vrm-springbone';

interface ModelProps {
	url: string
	url_anim: string
 scale: number
 position: [number, number, number]
 rotation: [number, number, number]
}

const VRMModel: React.FC<ModelProps> = ({ url, url_anim, position, rotation, scale }) => {
	const [vrm, setVrm] = useState<VRM | null>(null);
	const mixerRef = useRef<THREE.AnimationMixer | null>(null);
	const springBoneManagerRef = useRef<VRMSpringBoneManager | null>(null);

	useEffect(() => {
		const loader = new GLTFLoader();
		loader.register((parser) => new VRMLoaderPlugin(parser));
		loader.register((parser) => new VRMAnimationLoaderPlugin(parser));
		loader.load(url, (gltf) => {
			const vrmModel = gltf.userData.vrm as VRM;
			VRMUtils.removeUnnecessaryJoints(vrmModel.scene);
			springBoneManagerRef.current = vrmModel.springBoneManager as VRMSpringBoneManager;
			springBoneManagerRef.current?.reset();
			setVrm(vrmModel);
			if (vrmModel) {
				vrmModel.scene.rotation.set(...rotation);
				vrmModel.scene.position.set(...position);
				vrmModel.scene.scale.setScalar(scale);
			}
			const mixer = new THREE.AnimationMixer(vrmModel.scene);
			mixerRef.current = mixer;
			loader.load(url_anim, (animGltf) => {
				const vrmAnimations = animGltf.userData.vrmAnimations as VRMAnimation[];
				if (vrmAnimations && vrmAnimations.length > 0) {
					const clip = createVRMAnimationClip(vrmAnimations[0], vrmModel);
					mixer.clipAction(clip).play();
				}
			});
		});
	}, [url, url_anim, position, scale, rotation]);

	useFrame((state, delta) => {
		if (mixerRef.current) mixerRef.current.update(delta);
		if (springBoneManagerRef.current) springBoneManagerRef.current.update(delta);
		if (vrm) vrm.update(delta);
	});

	return vrm ? <primitive object={vrm.scene} /> : null;
};

export const VRMModelCanvas = () => {
	return (
		<div style={{ height: '100vh', width: '100vw' }}>
		<Canvas
		shadows
		gl={{
			//toneMapping: THREE.ACESFilmicToneMapping,
			//toneMapping: THREE.ReinhardToneMapping,
			toneMapping: THREE.NeutralToneMapping,
				toneMappingExposure: 1,
				alpha: true,
				powerPreference: "high-performance",
				antialias: true,
				//stencil: false,
				//depth: false
		}}
		camera={{ position: [1.2, 0, 0] }}>
		<color attach="background" args={["#000"]} /> {/* Light gray background */}
		<OrbitControls dampingFactor={0.05} rotateSpeed={0.1} zoomSpeed={0.5}/>
		<ambientLight intensity={10} />
		<pointLight position={[10, 10, 10]} />
		<VRMModel url="./models/t.vrm" url_anim="./models/default.vrma" position={[0, -0.6, 0]} rotation={[0, 89.5, 0]} scale={1} />
		</Canvas>
		</div>
	)
}
export default VRMModelCanvas;
