use bevy::prelude::*;

use super::components::{MaxSpeed, MoveTarget, Velocity};

/// Distance (in world units) at which an entity is considered to have arrived at its target.
const ARRIVAL_DISTANCE: f32 = 0.5;

/// For each entity with a MoveTarget, set Velocity to face the target at MaxSpeed,
/// and rotate the transform to face direction of motion.
pub fn steer_to_target(
    mut query: Query<(&mut Transform, &mut Velocity, &MoveTarget, &MaxSpeed)>,
    time: Res<Time>,
) {
    let dt = time.delta_secs();
    for (mut transform, mut velocity, target, max_speed) in &mut query {
        let to_target = target.0 - transform.translation;
        let distance = to_target.length();
        if distance <= ARRIVAL_DISTANCE {
            velocity.0 = Vec3::ZERO;
            continue;
        }
        let direction = to_target / distance;
        velocity.0 = direction * max_speed.0;

        // Rotate to face direction of motion, keeping Y as up (no pitch).
        // This gives a "ship banking" feel rather than nosediving toward targets at different altitudes.
        let flat = Vec3::new(direction.x, 0.0, direction.z);
        if flat.length_squared() > 1e-4 {
            let look = Transform::IDENTITY.looking_at(flat.normalize(), Vec3::Y);
            transform.rotation = transform.rotation.slerp(look.rotation, dt * 4.0);
        }
    }
}

/// Apply Velocity to Transform.translation.
pub fn integrate_velocity(mut query: Query<(&mut Transform, &Velocity)>, time: Res<Time>) {
    let dt = time.delta_secs();
    for (mut transform, velocity) in &mut query {
        transform.translation += velocity.0 * dt;
    }
}
