import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, } from 'react';
import { DynamicDrawUsage, Object3D } from 'three';
import { gpstoVec3 } from '../../utils/helpers';
import gsap from 'gsap';
export default forwardRef(function MarkersInstance({ count = 100, locations, temp = new Object3D() }, ref) {
    const circleRef = useRef(null);
    const dotRef = useRef(null);
    const dummies = useMemo(() => Array(count)
        .fill(() => null)
        .map(() => new Object3D()), [count]);
    useEffect(() => {
        // Set positions
        const alphas = [];
        for (let i = 0; i < locations.length; i++) {
            const { coordinates } = locations[i];
            const { lat, lng } = coordinates;
            const pos = gpstoVec3(lat, lng);
            temp.position.copy(pos);
            dummies[i].position.copy(pos);
            temp.lookAt(pos.multiplyScalar(1.1));
            temp.scale.multiplyScalar(0.01);
            temp.updateMatrix();
            dotRef.current.setMatrixAt(i, temp.matrix);
            dummies[i].rotation.copy(temp.rotation);
            temp.scale.set(1, 1, 1);
            temp.position.multiplyScalar(1.001);
            temp.updateMatrix();
            alphas.push(1);
            circleRef.current.setMatrixAt(i, temp.matrix);
        }
        // Update the instance
        circleRef.current.count = locations.length;
        circleRef.current.instanceMatrix.needsUpdate = true;
        circleRef.current.instanceMatrix.setUsage(DynamicDrawUsage);
        dotRef.current.count = locations.length;
        dotRef.current.instanceMatrix.needsUpdate = true;
        dotRef.current.instanceMatrix.setUsage(DynamicDrawUsage);
    }, [count, temp, locations, dummies]);
    useImperativeHandle(ref, () => ({
        impact: (i, shouldDisplay) => {
            const obj = dummies[i];
            dotRef.current.getMatrixAt(i, obj.matrix);
            const tl = gsap.timeline();
            const maxScale = 1.2;
            tl.set(obj.scale, {
                x: shouldDisplay ? 0.001 : maxScale,
                y: shouldDisplay ? 0.001 : maxScale,
                z: shouldDisplay ? 0.001 : maxScale,
            });
            tl.to(obj.scale, {
                x: shouldDisplay ? maxScale : 0.001,
                y: shouldDisplay ? maxScale : 0.001,
                z: shouldDisplay ? maxScale : 0.001,
                ease: shouldDisplay ? 'expo.out' : 'power2.in',
                duration: shouldDisplay ? 0.2 : 0.5,
                onUpdate: () => {
                    obj.updateMatrix();
                    dotRef.current.setMatrixAt(i, obj.matrix);
                    dotRef.current.instanceMatrix.needsUpdate = true;
                },
            });
        },
    }), [dummies]);
    return (React.createElement(React.Fragment, null,
        React.createElement("instancedMesh", { ref: circleRef, args: [undefined, undefined, count] },
            React.createElement("ringGeometry", { args: [0.02, 0.03, 48] }),
            React.createElement("meshBasicMaterial", { color: 'red' })),
        React.createElement("instancedMesh", { ref: dotRef, args: [undefined, undefined, count] },
            React.createElement("sphereGeometry", { args: [0.01, 8, 8] }),
            React.createElement("meshBasicMaterial", { color: 'red' }))));
});
