use bevy::{color::palettes::css::*, prelude::*};

fn main() {
    App::new()
        .add_plugins(DefaultPlugins.set(WindowPlugin {
            primary_window: Some(Window {
                resolution: (640, 480).into(),
                ..default()
            }),
            ..default()
        }))
        .insert_resource(ClearColor(WHITE.into()))
        .add_systems(Startup, setup_3d)
        .add_systems(Update, (move_camera_buttons, button_color))
        .run();
}

fn setup_3d(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    commands.spawn((
        Camera::default(),
        Camera3d::default(),
        AmbientLight {
            brightness: 1280.0,
            ..default()
        },
    ));

    commands.spawn((
        Mesh3d(meshes.add(Cuboid::default())),
        MeshMaterial3d(materials.add(StandardMaterial {
            base_color: RED.into(),
            ..Default::default()
        })),
        Transform::from_xyz(0.0, 0.0, -5.0),
    ));

    commands.spawn((
        Mesh3d(meshes.add(Cuboid::default())),
        MeshMaterial3d(materials.add(StandardMaterial {
            base_color: GREEN.into(),
            ..Default::default()
        })),
        Transform::from_xyz(0.0, 0.0, -10.0),
    ));

    commands.spawn((
        Mesh3d(meshes.add(Cuboid::default())),
        MeshMaterial3d(materials.add(StandardMaterial {
            base_color: BLUE.into(),
            ..Default::default()
        })),
        Transform::from_xyz(0.0, 0.0, -20.0),
    ));

    commands
        .spawn(Node {
            align_self: AlignSelf::End,
            justify_self: JustifySelf::Center,
            ..default()
        })
        .with_children(|parent| {
            parent.spawn((
                Node {
                    padding: UiRect::all(Val::Px(20.0)),
                    margin: UiRect::all(Val::Px(10.0)),
                    ..default()
                },
                Button,
                children![
                    Text::new("<-"),
                    Node {
                        align_self: AlignSelf::Center,
                        justify_self: JustifySelf::Center,
                        ..default()
                    },
                ],
                Movement(0.1),
                BackgroundColor(ORANGE.into()),
            ));
            parent.spawn((
                Node {
                    align_self: AlignSelf::Center,
                    justify_self: JustifySelf::Center,
                    ..default()
                },
                Text::new("movement"),
                TextColor(BLACK.into()),
            ));
            parent.spawn((
                Node {
                    padding: UiRect::all(Val::Px(20.0)),
                    margin: UiRect::all(Val::Px(10.0)),
                    ..default()
                },
                Button,
                children![
                    Text::new("->"),
                    Node {
                        align_self: AlignSelf::Center,
                        justify_self: JustifySelf::Center,
                        ..default()
                    },
                ],
                Movement(-0.1),
                BackgroundColor(ORANGE.into()),
            ));
        });
}

fn button_color(
    mut query: Query<(&Interaction, &mut BackgroundColor), (Changed<Interaction>, With<Button>)>,
) {
    query.iter_mut().for_each(|(i, mut bg)| {
        bg.0 = match i {
            Interaction::None => ORANGE.into(),
            Interaction::Hovered => ORANGE_RED.into(),
            Interaction::Pressed => RED.into(),
        };
    });
}

#[derive(Component)]
struct Movement(f32);

fn move_camera_buttons(
    query: Query<(&Interaction, &Movement), With<Button>>,
    mut camera: Single<&mut Transform, With<Camera>>,
) {
    query.iter().for_each(|(i, m)| {
        if let (Interaction::Pressed, Movement(speed)) = (i, m) {
            camera.translation.x += speed;
        }
    });
}
