import * as THREE from "three";
import { Html, useGLTF } from "@react-three/drei";
import { useRef } from "react";
import { useFrame } from "@react-three/fiber";
import { useSceneContext } from "../../scene/sceneContext";
import { useSelectedUserStore } from "../../../store/collaboration/useCollabStore";
import { getUserData } from "../../../functions/getUserData";
import { getAvatarColor } from "../functions/getAvatarColor";

import CollabUserIcon from "./collabUserIcon";
import camModel from "../../../assets/gltf-glb/camera face 2.gltf";

const CamModelsGroup = () => {
    const { collabUsersStore } = useSceneContext();
    const { collabUsers } = collabUsersStore();
    const model: any = useGLTF(camModel);
    const { userId: currentUserId } = getUserData();

    return (
        <group name="Cam-Model-Group">
            {collabUsers
                .filter((user) => user.userId !== currentUserId)
                .map((user, index) => (
                    <CamModel key={user.userId} index={index} user={user} model={model.scene as THREE.Object3D} />
                ))}
        </group>
    );
};

const CamModel = ({ user, model, index }: { user: CollabUsersScheme; model: THREE.Object3D; index: number }) => {
    const ref = useRef<THREE.Group>(null);

    const targetPos = new THREE.Vector3();
    const targetQuat = new THREE.Quaternion();
    const { selectedUser, updateLocation } = useSelectedUserStore();

    useFrame((_, delta) => {
        if (ref.current) {
            targetPos.set(user.camData.position.x, user.camData.position.y, user.camData.position.z);

            targetQuat.setFromEuler(new THREE.Euler(user.camData.rotation.x, user.camData.rotation.y, user.camData.rotation.z));

            ref.current.position.lerp(targetPos, 5 * delta);
            ref.current.quaternion.slerp(targetQuat, 5 * delta);

            if (selectedUser && selectedUser.id === user.userId) {
                const pos = ref.current.position;
                const rot = new THREE.Euler().setFromQuaternion(ref.current.quaternion);

                updateLocation({
                    position: { x: pos.x, y: pos.y, z: pos.z },
                    rotation: { x: rot.x, y: rot.y, z: rot.z },
                    target: user.camData.target,
                });
            }
        }
    });

    return (
        <group visible={selectedUser ? selectedUser.id !== user.userId : true} ref={ref}>
            <primitive object={model.clone()} />
            <Html
                as="div"
                center
                zIndexRange={[1, 0]}
                sprite
                style={{
                    color: "white",
                    textAlign: "center",
                    fontFamily: "Arial, sans-serif",
                    transition: "opacity .2s ease",
                }}
                position={[-0.015, 0, 0.7]}
            >
                <CollabUserIcon
                    userImage={""}
                    userName={user.userName}
                    id={user.userId}
                    color={getAvatarColor(index, user.userId)}
                    position={user.camData.position}
                    rotation={user.camData.rotation}
                    target={user.camData.target}
                />
            </Html>
        </group>
    );
};

export default CamModelsGroup;
