use crate::ecs::world::World;

#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod animation;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod asset;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod batch;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod debug;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod effects;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod entity;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod environment;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod lighting;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod material;
#[cfg(all(feature = "mcp", feature = "physics", not(target_arch = "wasm32")))]
pub(crate) mod physics;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod scripting;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod text;
#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) mod transform;

#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
fn resolve_entity(world: &World, name: &str) -> Result<freecs::Entity, crate::mcp::McpResponse> {
    world
        .resources
        .entity_names
        .get(name)
        .copied()
        .ok_or_else(|| crate::mcp::McpResponse::Error(format!("Entity '{}' not found", name)))
}

#[cfg(all(feature = "mcp", not(target_arch = "wasm32")))]
pub(crate) fn process_single_mcp_command(
    world: &mut World,
    cmd: crate::mcp::McpCommand,
) -> crate::mcp::McpResponse {
    use crate::mcp::{McpCommand, McpResponse};

    match cmd {
        McpCommand::ListEntities(_) => {
            let names: Vec<String> = world.resources.entity_names.keys().cloned().collect();
            McpResponse::EntityList(names)
        }
        McpCommand::QueryEntity(request) => {
            entity::mcp_query_entity(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SpawnEntity(request) => entity::mcp_spawn_entity(world, request),
        McpCommand::DespawnEntity(request) => entity::mcp_despawn_entity(world, request.name),
        McpCommand::SetPosition(request) => {
            transform::mcp_set_position(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SetRotation(request) => {
            transform::mcp_set_rotation(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SetScale(request) => {
            transform::mcp_set_scale(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SetMaterialColor(request) => {
            material::mcp_set_material_color(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SetEmissive(request) => {
            material::mcp_set_emissive(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SetParent(request) => {
            transform::mcp_set_parent(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::LoadAsset(request) => asset::mcp_load_asset(world, request),
        McpCommand::SpawnPrefab(request) => asset::mcp_spawn_prefab(world, request),
        McpCommand::ListLoadedAssets(_) => asset::mcp_list_loaded_assets(world),
        McpCommand::ClearScene(_) => entity::mcp_clear_scene(world),
        McpCommand::SetAtmosphere(request) => environment::mcp_set_atmosphere(world, request),
        McpCommand::LoadHdr(request) => environment::mcp_load_hdr(world, request),
        McpCommand::SpawnLight(request) => lighting::mcp_spawn_light(world, request),
        McpCommand::SetLight(request) => {
            lighting::mcp_set_light(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::AddLine(request) => debug::mcp_add_line(world, request),
        McpCommand::AddLines(request) => debug::mcp_add_lines(world, request),
        McpCommand::ClearLines(_) => debug::mcp_clear_lines(world),
        McpCommand::SetGraphics(request) => environment::mcp_set_graphics(world, request),
        McpCommand::SpawnWater(request) => environment::mcp_spawn_water(world, request),
        McpCommand::SpawnHudText(request) => text::mcp_spawn_hud_text(world, request),
        McpCommand::SetHudText(request) => {
            text::mcp_set_hud_text(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SetCamera(request) => lighting::mcp_set_camera(world, request),
        McpCommand::SetScript(request) => {
            scripting::mcp_set_script(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::RemoveScript(request) => {
            scripting::mcp_remove_script(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SetGameState(request) => scripting::mcp_set_game_state(world, request),
        McpCommand::GetGameState(request) => scripting::mcp_get_game_state(world, request),
        McpCommand::SetVisibility(request) => {
            entity::mcp_set_visibility(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::PlayAnimation(request) => {
            animation::mcp_play_animation(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::StopAnimation(request) => {
            animation::mcp_stop_animation(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::ListAnimations(request) => {
            animation::mcp_list_animations(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SpawnParticles(request) => effects::mcp_spawn_particles(world, request),
        McpCommand::SetParticles(request) => {
            effects::mcp_set_particles(world, request).unwrap_or_else(|error| error)
        }
        #[cfg(feature = "physics")]
        McpCommand::AddRigidBody(request) => {
            physics::mcp_add_rigid_body(world, request).unwrap_or_else(|error| error)
        }
        #[cfg(not(feature = "physics"))]
        McpCommand::AddRigidBody(_) => {
            McpResponse::Error("Physics feature not enabled".to_string())
        }
        #[cfg(feature = "physics")]
        McpCommand::AddCollider(request) => {
            physics::mcp_add_collider(world, request).unwrap_or_else(|error| error)
        }
        #[cfg(not(feature = "physics"))]
        McpCommand::AddCollider(_) => McpResponse::Error("Physics feature not enabled".to_string()),
        #[cfg(feature = "physics")]
        McpCommand::ApplyImpulse(request) => {
            physics::mcp_apply_impulse(world, request).unwrap_or_else(|error| error)
        }
        #[cfg(not(feature = "physics"))]
        McpCommand::ApplyImpulse(_) => {
            McpResponse::Error("Physics feature not enabled".to_string())
        }
        #[cfg(feature = "physics")]
        McpCommand::ApplyForce(request) => {
            physics::mcp_apply_force(world, request).unwrap_or_else(|error| error)
        }
        #[cfg(not(feature = "physics"))]
        McpCommand::ApplyForce(_) => McpResponse::Error("Physics feature not enabled".to_string()),
        #[cfg(feature = "physics")]
        McpCommand::SetVelocity(request) => {
            physics::mcp_set_velocity(world, request).unwrap_or_else(|error| error)
        }
        #[cfg(not(feature = "physics"))]
        McpCommand::SetVelocity(_) => McpResponse::Error("Physics feature not enabled".to_string()),
        McpCommand::Spawn3dText(request) => text::mcp_spawn_3d_text(world, request),
        McpCommand::SpawnDecal(request) => effects::mcp_spawn_decal(world, request),
        McpCommand::SetMaterial(request) => {
            material::mcp_set_material(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::SetCastsShadow(request) => {
            material::mcp_set_casts_shadow(world, request).unwrap_or_else(|error| error)
        }
        McpCommand::GetInput(_) => debug::mcp_get_input(world),
        McpCommand::GetTime(_) => debug::mcp_get_time(world),
        McpCommand::Batch(request) => {
            let results = batch::process_batch_operations(world, request.operations);
            McpResponse::BatchResult(results)
        }
        McpCommand::RunCommands(request) => {
            let results = batch::process_text_commands(world, &request.commands);
            McpResponse::BatchResult(results)
        }
    }
}
