use crate::ecs::world::World;
use crate::mcp::McpResponse;

pub(crate) fn mcp_add_line(world: &mut World, request: crate::mcp::AddLineRequest) -> McpResponse {
    use crate::ecs::lines::components::{Line, Lines};
    use crate::ecs::world::{GLOBAL_TRANSFORM, LINES, LOCAL_TRANSFORM, LOCAL_TRANSFORM_DIRTY};

    let lines_entity = world.query_entities(LINES).next().unwrap_or_else(|| {
        let entity = world.spawn_entities(
            LINES | LOCAL_TRANSFORM | LOCAL_TRANSFORM_DIRTY | GLOBAL_TRANSFORM,
            1,
        )[0];
        world.set_local_transform(
            entity,
            crate::ecs::transform::components::LocalTransform::default(),
        );
        world.set_local_transform_dirty(
            entity,
            crate::ecs::transform::components::LocalTransformDirty,
        );
        world.set_global_transform(
            entity,
            crate::ecs::transform::components::GlobalTransform::default(),
        );
        world.set_lines(entity, Lines::default());
        entity
    });

    let color_vec = request
        .color
        .map(|c| nalgebra_glm::Vec4::new(c[0], c[1], c[2], c[3]))
        .unwrap_or(nalgebra_glm::Vec4::new(1.0, 1.0, 1.0, 1.0));

    if let Some(lines) = world.get_lines_mut(lines_entity) {
        lines.push(Line {
            start: nalgebra_glm::Vec3::new(request.start[0], request.start[1], request.start[2]),
            end: nalgebra_glm::Vec3::new(request.end[0], request.end[1], request.end[2]),
            color: color_vec,
        });
    }

    McpResponse::Success("Added line".to_string())
}

pub(crate) fn mcp_add_lines(
    world: &mut World,
    request: crate::mcp::AddLinesRequest,
) -> McpResponse {
    use crate::ecs::lines::components::{Line, Lines};
    use crate::ecs::world::{GLOBAL_TRANSFORM, LINES, LOCAL_TRANSFORM, LOCAL_TRANSFORM_DIRTY};

    let lines_entity = world.query_entities(LINES).next().unwrap_or_else(|| {
        let entity = world.spawn_entities(
            LINES | LOCAL_TRANSFORM | LOCAL_TRANSFORM_DIRTY | GLOBAL_TRANSFORM,
            1,
        )[0];
        world.set_local_transform(
            entity,
            crate::ecs::transform::components::LocalTransform::default(),
        );
        world.set_local_transform_dirty(
            entity,
            crate::ecs::transform::components::LocalTransformDirty,
        );
        world.set_global_transform(
            entity,
            crate::ecs::transform::components::GlobalTransform::default(),
        );
        world.set_lines(entity, Lines::default());
        entity
    });

    let count = request.lines.len();
    if let Some(lines_component) = world.get_lines_mut(lines_entity) {
        for line in request.lines {
            let color = line
                .color
                .map(|c| nalgebra_glm::Vec4::new(c[0], c[1], c[2], c[3]))
                .unwrap_or(nalgebra_glm::Vec4::new(1.0, 1.0, 1.0, 1.0));
            lines_component.push(Line {
                start: nalgebra_glm::Vec3::new(line.start[0], line.start[1], line.start[2]),
                end: nalgebra_glm::Vec3::new(line.end[0], line.end[1], line.end[2]),
                color,
            });
        }
    }

    McpResponse::Success(format!("Added {} lines", count))
}

pub(crate) fn mcp_clear_lines(world: &mut World) -> McpResponse {
    use crate::ecs::world::LINES;

    for entity in world.query_entities(LINES).collect::<Vec<_>>() {
        if let Some(lines) = world.get_lines_mut(entity) {
            lines.clear();
        }
    }

    McpResponse::Success("Cleared all lines".to_string())
}

pub(crate) fn mcp_get_input(world: &mut World) -> McpResponse {
    use crate::ecs::input::resources::MouseState;
    use winit::event::ElementState;

    let pressed_keys: Vec<String> = world
        .resources
        .input
        .keyboard
        .keystates
        .iter()
        .filter(|(_, state)| **state == ElementState::Pressed)
        .map(|(key, _)| format!("{:?}", key))
        .collect();

    let mouse_position = [
        world.resources.input.mouse.position.x,
        world.resources.input.mouse.position.y,
    ];

    let mouse_state = world.resources.input.mouse.state;
    let mouse_buttons = [
        mouse_state.contains(MouseState::LEFT_CLICKED),
        mouse_state.contains(MouseState::MIDDLE_CLICKED),
        mouse_state.contains(MouseState::RIGHT_CLICKED),
    ];

    McpResponse::InputState {
        pressed_keys,
        mouse_position,
        mouse_buttons,
    }
}

pub(crate) fn mcp_get_time(world: &mut World) -> McpResponse {
    let elapsed_time = world.resources.window.timing.uptime_milliseconds as f32 / 1000.0;

    McpResponse::TimeInfo {
        delta_time: world.resources.window.timing.delta_time,
        elapsed_time,
    }
}
