use crate::ecs::world::{
    INSTANCED_MESH, LOCAL_TRANSFORM_DIRTY, PARENT, RENDER_MESH, World, components::GlobalTransform,
};

use crate::prelude::*;
pub fn mark_local_transform_dirty(world: &mut World, entity: freecs::Entity) {
    if world.resources.transform_state.children_cache.is_empty()
        && world.core.query_entities(PARENT).count() > 0
    {
        validate_and_rebuild_children_cache(world);
    }

    if !world.core.entity_has_components(entity, PARENT)
        && !world
            .resources
            .transform_state
            .children_cache
            .contains_key(&entity)
    {
        let new_global = match world.core.get_local_transform(entity) {
            Some(local_transform) => local_transform.as_matrix(),
            None => nalgebra_glm::Mat4::identity(),
        };
        if let Some(global_transform) = world.core.get_global_transform_mut(entity) {
            *global_transform = GlobalTransform(new_global);
        }
        if world
            .core
            .entity_has_components(entity, LOCAL_TRANSFORM_DIRTY)
        {
            world.core.remove_local_transform_dirty(entity);
        }
        if world.core.entity_has_components(entity, RENDER_MESH)
            || world.core.entity_has_components(entity, INSTANCED_MESH)
        {
            world
                .resources
                .mesh_render_state
                .mark_transform_dirty(entity);
        }
        return;
    }

    let mut stack = vec![entity];

    while let Some(current) = stack.pop() {
        world.resources.transform_state.dirty_entities.push(current);

        if let Some(children) = world.resources.transform_state.children_cache.get(&current) {
            for &child in children {
                stack.push(child);
            }
        }
    }
}
