use nightshade::ecs::bounding_volume::components::BoundingVolume;
use nightshade::ecs::generational_registry::registry_entry_by_name;
use nightshade::prelude::*;

fn resolve_bounding_volume(world: &World, mesh_name: &str) -> BoundingVolume {
    if let Some(mesh) = registry_entry_by_name(&world.resources.mesh_cache.registry, mesh_name)
        && let Some(bv) = &mesh.bounding_volume
    {
        return *bv;
    }
    BoundingVolume::from_mesh_type(mesh_name)
}

pub fn ensure_bounding_volumes(world: &mut World) {
    let render_mesh_entities: Vec<Entity> = world
        .core
        .query_entities(RENDER_MESH)
        .filter(|entity| !world.core.entity_has_components(*entity, BOUNDING_VOLUME))
        .collect();

    for entity in render_mesh_entities {
        let mesh_name = world
            .core
            .get_render_mesh(entity)
            .map(|rm| rm.name.clone())
            .unwrap_or_default();

        let bounding_volume = resolve_bounding_volume(world, &mesh_name);
        world.core.add_components(entity, BOUNDING_VOLUME);
        world.core.set_bounding_volume(entity, bounding_volume);
    }

    let instanced_mesh_entities: Vec<Entity> = world
        .core
        .query_entities(INSTANCED_MESH)
        .filter(|entity| !world.core.entity_has_components(*entity, BOUNDING_VOLUME))
        .collect();

    for entity in instanced_mesh_entities {
        let mesh_name = world
            .core
            .get_instanced_mesh(entity)
            .map(|im| im.mesh_name.clone())
            .unwrap_or_default();

        let bounding_volume = resolve_bounding_volume(world, &mesh_name);
        world.core.add_components(entity, BOUNDING_VOLUME);
        world.core.set_bounding_volume(entity, bounding_volume);
    }
}

pub fn query_number_of_lines(world: &World) -> usize {
    world
        .core
        .query_entities(LINES)
        .map(|entity| {
            world
                .core
                .get_lines(entity)
                .map(|lines| lines.lines.len())
                .unwrap_or(0)
        })
        .sum::<usize>()
}
