import React, {
    FC,
    useRef,
    useState,
} from 'react'
import { useControls } from 'leva';
import _ from 'lodash';
import { Vector3 } from 'three';
import {
    Box,
    OrbitControls,
    PerspectiveCamera,
} from '@react-three/drei';
import { Canvas } from '@react-three/fiber';
import {
    Entity,
    Facet,
    rad,
    useAnimationFrame,
    useECS,
    useQuery,
    useSystem,
} from '@react-ecs/core';
import { ThreeView } from '@react-ecs/three';
class Spinning extends Facet<Spinning> {
    rotation = new Vector3(0, 0, 0);
}
const SpinningSystem = () => {
    const query = useQuery(e => e.hasAll(ThreeView, Spinning));
    return useSystem((dt: number) => {
        query.loop([ThreeView, Spinning], (e, [view, spin]) => {
            const transform = view.ref.current!;
            const rotation = spin.rotation.clone().multiplyScalar(dt);
            const newRotation = transform.rotation
                .toVector3()
                .add(rotation);
            transform.rotation.setFromVector3(newRotation);
        });
    });
};
const SpinCube = ({ amount }) => {
    return (
        <Entity>
            <Spinning rotation={new Vector3(amount.x, amount.y, amount.z)} />
            <ThreeView>
                <Box position={[Math.random() * 3, Math.random() * 3, 0]} scale={3} rotation={[rad(45), rad(45), 0]}>
                    <meshLambertMaterial />
                </Box>
            </ThreeView>
        </Entity>
    );
};
const Generator = (props) => {
    const tick = useRef(0)
    const [gen, setGen] = useState(0);
    useSystem(dt => {
        tick.current += dt;
        if (tick.current > 1) {
            tick.current = 0
            setGen(gen + 1)
        }
    })
    return <>{_.times(5, _ => <SpinCube key={Math.random()} amount={{ x: 1, y: 1, z: 1}} />)}</>
}
export const EntityManagementScene: FC = () => {
    const ECS = useECS();
    useAnimationFrame(ECS.update);
    const { amount } = useControls('spin', {amount: {value: { x: 1, y: 1, z: 1}}})
    const del = () => ECS.engine.removeEntity(ECS.engine.entities[0])
    return (
        <>
            <button onClick={del}>Delete</button>
            <Canvas>
                <OrbitControls />
                <PerspectiveCamera makeDefault position={[0, 0, 8]}>
                    <ambientLight intensity={.2} />
                    <directionalLight position={[1, 1, 1]} />
                </PerspectiveCamera>
                <ECS.Provider>
                    <SpinningSystem />
                    <Generator />
                </ECS.Provider>
            </Canvas>
        </>
    );
};