pub use bevy::prelude::*;

pub fn demo_3d(
    mut camera_query: Query<&mut Transform, With<Camera3d>>,
    mut mouse_events: EventReader<bevy::input::mouse::MouseMotion>,
    mouse_input: Res<ButtonInput<MouseButton>>,
    key_input: Res<ButtonInput<KeyCode>>,
    time: Res<Time>,
) {
    let raw_mouse_motion: Vec2 = mouse_events.read().map(|e| e.delta).sum();

    if mouse_input.pressed(MouseButton::Right) {
        let move_forward = key_input.pressed(KeyCode::KeyW);
        let move_back = key_input.pressed(KeyCode::KeyS);
        let move_left = key_input.pressed(KeyCode::KeyA);
        let move_right = key_input.pressed(KeyCode::KeyD);
        let move_up = key_input.pressed(KeyCode::Space) || key_input.pressed(KeyCode::KeyE);
        let move_down = key_input.pressed(KeyCode::ControlLeft) || key_input.pressed(KeyCode::KeyQ);

        let raw_movement = Vec3 {
            x: match (move_right, move_left) {
                (true, false) => 1.0,
                (false, true) => -1.0,
                _ => 0.0,
            },
            y: match (move_up, move_down) {
                (true, false) => 1.0,
                (false, true) => -1.0,
                _ => 0.0,
            },
            z: match (move_back, move_forward) {
                (true, false) => 1.0,
                (false, true) => -1.0,
                _ => 0.0,
            },
        };

        for mut transform in camera_query.iter_mut() {
            let mouse_motion = raw_mouse_motion * Vec2::new(-1.0, -1.0) * 0.002;
            transform.rotate_axis(Dir3::Y, mouse_motion.x);
            transform.rotate_local_x(mouse_motion.y);

            let local_movement = raw_movement * time.delta_secs() * 10.0;
            let movement = transform.rotation * local_movement;
            transform.translation += movement;
        }
    }
}
