use crate::{GameState, global_observer, loading_assets::UIAssets, utils::billboards::Billboard};
use bevy::prelude::*;
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
use ops::sin;

#[derive(Component, Reflect)]
#[reflect(Component)]
struct TargetMarker;

#[derive(Event)]
pub enum MarkerEvent {
    Spawn(Entity),
    Despawn,
}

pub fn plugin(app: &mut App) {
    app.add_systems(Update, move_marker.run_if(in_state(GameState::Playing)));
    global_observer!(app, marker_event);
}

fn move_marker(mut query: Query<&mut Transform, With<TargetMarker>>, time: Res<Time>) {
    for mut transform in query.iter_mut() {
        transform.translation = Vec3::new(0., 3. + (sin(time.elapsed_secs() * 6.) * 0.2), 0.);
    }
}

fn marker_event(
    trigger: Trigger<MarkerEvent>,
    mut commands: Commands,
    assets: Res<UIAssets>,
    mut sprite_params: Sprite3dParams,
    marker: Query<Entity, With<TargetMarker>>,
) {
    for m in marker.iter() {
        commands.entity(m).despawn();
    }

    let MarkerEvent::Spawn(target) = trigger.event() else {
        return;
    };

    let id = commands
        .spawn((
            Name::new("aim-marker"),
            Billboard,
            TargetMarker,
            Transform::default(),
            Sprite3dBuilder {
                image: assets.head_selector.clone(),
                pixels_per_metre: 30.,
                alpha_mode: AlphaMode::Blend,
                unlit: true,
                ..default()
            }
            .bundle(&mut sprite_params),
        ))
        .id();

    commands.entity(*target).add_child(id);
}
