import React, { useEffect, useMemo, useRef, useState } from 'react'
import * as THREE from "three";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { clone } from "three/examples/jsm/utils/SkeletonUtils";
import { useFrame, useLoader, useThree } from "@react-three/fiber";
import { CCDIKSolver, CCDIKHelper, } from "three/examples/jsm/animation/CCDIKSolver";
type IKInstanceProps = {
    modelUrl: string;
    ikSolver: any;
    setIkSolver: any
    robot: any;
    groupRef: React.RefObject<THREE.Group>;
    processes: any;
    setArmBotCurvePoints: any
};
function IKInstance({ modelUrl, setIkSolver, ikSolver, robot, groupRef, processes, setArmBotCurvePoints }: IKInstanceProps) {
  
    const { scene } = useThree();
    const gltf = useLoader(GLTFLoader, modelUrl, (loader) => {
        const draco = new DRACOLoader();
        draco.setDecoderPath("https://cdn.jsdelivr.net/npm/three@0.160.0/examples/jsm/libs/draco/");
        loader.setDRACOLoader(draco);
    });
    const cloned = useMemo(() => clone(gltf?.scene), [gltf]);
    const targetBoneName = "Target";
    const skinnedMeshName = "link_0";
    useEffect(() => {
        if (!gltf) return;
        const OOI: any = {};
        cloned.traverse((n: any) => {
            if (n.name === targetBoneName) OOI.Target_Bone = n;
            if (n.name === skinnedMeshName) OOI.Skinned_Mesh = n;
        });
        if (!OOI.Target_Bone || !OOI.Skinned_Mesh) return;
        const iks = [
            {
                target: 7,
                effector: 6,
                links: [
                    {
                        index: 5,
                        enabled: true,
                        rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0),
                        rotationMax: new THREE.Vector3(Math.PI / 2, 0, 0),
                    },
                    {
                        index: 4,
                        enabled: true,
                        rotationMin: new THREE.Vector3(-Math.PI / 2, 0, 0),
                        rotationMax: new THREE.Vector3(0, 0, 0),
                    },
                    {
                        index: 3,
                        enabled: true,
                        rotationMin: new THREE.Vector3(0, 0, 0),
                        rotationMax: new THREE.Vector3(2, 0, 0),
                    },
                    { index: 1, enabled: true, limitation: new THREE.Vector3(0, 1, 0) },
                    { index: 0, enabled: false, limitation: new THREE.Vector3(0, 0, 0) },
                ],
            },
        ];

        const solver = new CCDIKSolver(OOI.Skinned_Mesh, iks);
        setIkSolver(solver);

        const helper = new CCDIKHelper(OOI.Skinned_Mesh, iks, 0.05);
        // if (solver) {
        //     const bone = solver.mesh.skeleton.bones.find(
        //         (b: any) => b.name === targetBoneName
        //     ) ?? "";
        //     if (bone) {
        //         const position = new THREE.Vector3();
        //         bone.getWorldPosition(position);
        //         console.log("world position", position.x, position.y, position.z); // this is the bone's world position
        //     }
        // }
        scene.add(helper)


    }, [gltf]);

    return (
        <>
            <group ref={groupRef} position={robot.position} rotation={robot.rotation}>
                <primitive
                    uuid={"ArmBot-X200"}
                    object={cloned}
                    scale={[1, 1, 1]}
                    name={`arm-bot11`}
                />
            </group>
        </>
    )
}

export default IKInstance;