use super::components::{GrassConfig, GrassInteractor, GrassRegion, GrassSpecies};
use crate::ecs::GRASS_INTERACTOR;
use crate::ecs::GRASS_REGION;
use crate::ecs::world::World;
use freecs::Entity;
use nalgebra_glm::Vec3;

pub fn spawn_grass_region(world: &mut World, config: GrassConfig) -> Entity {
    let entity = world.spawn_entities(GRASS_REGION, 1)[0];
    let region = GrassRegion::new().with_config(config);
    world.set_grass_region(entity, region);
    entity
}

pub fn spawn_grass_region_at(world: &mut World, position: Vec3, config: GrassConfig) -> Entity {
    let entity = world.spawn_entities(GRASS_REGION, 1)[0];
    let half_extent = config.stream_radius + 50.0;
    let region = GrassRegion::new().with_config(config).with_bounds(
        Vec3::new(
            position.x - half_extent,
            position.y - 50.0,
            position.z - half_extent,
        ),
        Vec3::new(
            position.x + half_extent,
            position.y + 100.0,
            position.z + half_extent,
        ),
    );
    world.set_grass_region(entity, region);
    entity
}

pub fn add_grass_species(world: &mut World, entity: Entity, species: GrassSpecies, weight: f32) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.add_species(species, weight);
    }
}

pub fn set_grass_species(
    world: &mut World,
    entity: Entity,
    species: Vec<GrassSpecies>,
    weights: Vec<f32>,
) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.species = species;
        region.species_weights = weights;
    }
}

pub fn update_grass_player_position(world: &mut World, entity: Entity, position: Vec3) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.set_player_position(position);
    }
}

pub fn set_grass_wind(world: &mut World, entity: Entity, strength: f32, frequency: f32) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.config.wind_strength = strength;
        region.config.wind_frequency = frequency;
    }
}

pub fn set_grass_wind_direction(
    world: &mut World,
    entity: Entity,
    direction_x: f32,
    direction_z: f32,
) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        let len = (direction_x * direction_x + direction_z * direction_z).sqrt();
        if len > 0.0001 {
            region.config.wind_direction = [direction_x / len, direction_z / len];
        }
    }
}

pub fn set_grass_density(world: &mut World, entity: Entity, blades_per_patch: u32) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.config.blades_per_patch = blades_per_patch;
    }
}

pub fn set_grass_shadows(world: &mut World, entity: Entity, cast: bool, receive: bool) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.config.cast_shadows = cast;
        region.config.receive_shadows = receive;
    }
}

pub fn enable_grass(world: &mut World, entity: Entity, enabled: bool) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.enabled = enabled;
    }
}

pub fn enable_grass_interactors(world: &mut World, entity: Entity, enabled: bool) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.config.interactors_enabled = enabled;
    }
}

pub fn set_grass_terrain(
    world: &mut World,
    entity: Entity,
    terrain_config: crate::ecs::terrain::TerrainConfig,
) {
    if let Some(region) = world.get_grass_region_mut(entity) {
        region.set_terrain(terrain_config);
    }
}

pub fn spawn_grass_interactor(world: &mut World, radius: f32, strength: f32) -> Entity {
    let entity = world.spawn_entities(GRASS_INTERACTOR, 1)[0];
    world.set_grass_interactor(entity, GrassInteractor::new(radius, strength));
    entity
}

pub fn attach_grass_interactor(world: &mut World, entity: Entity, radius: f32, strength: f32) {
    world.set_grass_interactor(entity, GrassInteractor::new(radius, strength));
}
