use crate::{
    GameState,
    tb_entities::{Platform, PlatformTarget},
};
use bevy::{math::ops::sin, prelude::*};
use bevy_trenchbroom::prelude::*;

#[derive(Component, Reflect, Default, Debug)]
#[reflect(Component)]
struct ActivePlatform {
    pub start: Vec3,
    pub target: Vec3,
}

pub fn plugin(app: &mut App) {
    app.register_type::<ActivePlatform>();
    app.add_systems(OnEnter(GameState::Playing), init);
    app.add_systems(Update, move_active.run_if(in_state(GameState::Playing)));
}

fn init(
    mut commands: Commands,
    uninit_platforms: Query<
        (Entity, &Target, &Transform),
        (Without<ActivePlatform>, With<Platform>),
    >,
    targets: Query<(&PlatformTarget, &Transform)>,
) {
    for (e, target, transform) in uninit_platforms.iter() {
        let Some(target) = targets
            .iter()
            .find(|(t, _)| t.targetname == target.target.clone().unwrap_or_default())
            .map(|(_, t)| t.translation)
        else {
            continue;
        };

        let platform = ActivePlatform {
            start: transform.translation,
            target,
        };

        commands.entity(e).insert(platform);
    }
}

fn move_active(time: Res<Time>, mut platforms: Query<(&mut Transform, &mut ActivePlatform)>) {
    for (mut transform, active) in platforms.iter_mut() {
        let t = (sin(time.elapsed_secs() * 0.4) + 1.) / 2.;

        transform.translation = active.start.lerp(active.target, t);
    }
}
