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

pub(crate) fn process_batch_operations(
    world: &mut World,
    operations: Vec<crate::mcp::BatchOperation>,
) -> Vec<McpResponse> {
    let mut results = Vec::with_capacity(operations.len());

    for operation in operations {
        let response = match operation.operation.to_lowercase().as_str() {
            "spawn_entity" => {
                let (Some(name), Some(mesh)) = (operation.name, operation.mesh) else {
                    results.push(McpResponse::Error(
                        "spawn_entity requires 'name' and 'mesh' fields".to_string(),
                    ));
                    continue;
                };
                let position = operation.position.unwrap_or([0.0, 0.0, 0.0]);
                super::entity::mcp_spawn_entity(
                    world,
                    crate::mcp::SpawnEntityRequest {
                        name,
                        mesh,
                        position,
                        scale: operation.scale,
                        color: operation.color,
                        emissive: operation.emissive,
                        parent: operation.parent,
                        alpha: operation.alpha,
                    },
                )
            }
            "despawn_entity" => {
                let Some(name) = operation.name else {
                    results.push(McpResponse::Error(
                        "despawn_entity requires 'name' field".to_string(),
                    ));
                    continue;
                };
                super::entity::mcp_despawn_entity(world, name)
            }
            "set_position" => {
                let (Some(name), Some(position)) = (operation.name, operation.position) else {
                    results.push(McpResponse::Error(
                        "set_position requires 'name' and 'position' fields".to_string(),
                    ));
                    continue;
                };
                super::transform::mcp_set_position(
                    world,
                    crate::mcp::SetPositionRequest { name, position },
                )
                .unwrap_or_else(|error| error)
            }
            "set_rotation" => {
                let (Some(name), Some(rotation)) = (operation.name, operation.rotation) else {
                    results.push(McpResponse::Error(
                        "set_rotation requires 'name' and 'rotation' fields".to_string(),
                    ));
                    continue;
                };
                super::transform::mcp_set_rotation(
                    world,
                    crate::mcp::SetRotationRequest { name, rotation },
                )
                .unwrap_or_else(|error| error)
            }
            "set_scale" => {
                let (Some(name), Some(scale)) = (operation.name, operation.scale) else {
                    results.push(McpResponse::Error(
                        "set_scale requires 'name' and 'scale' fields".to_string(),
                    ));
                    continue;
                };
                super::transform::mcp_set_scale(world, crate::mcp::SetScaleRequest { name, scale })
                    .unwrap_or_else(|error| error)
            }
            "set_material_color" => {
                let (Some(name), Some(color)) = (operation.name, operation.color) else {
                    results.push(McpResponse::Error(
                        "set_material_color requires 'name' and 'color' fields".to_string(),
                    ));
                    continue;
                };
                super::material::mcp_set_material_color(
                    world,
                    crate::mcp::SetMaterialColorRequest { name, color },
                )
                .unwrap_or_else(|error| error)
            }
            "set_emissive" => {
                let (Some(name), Some(emissive)) = (operation.name, operation.emissive) else {
                    results.push(McpResponse::Error(
                        "set_emissive requires 'name' and 'emissive' fields".to_string(),
                    ));
                    continue;
                };
                super::material::mcp_set_emissive(
                    world,
                    crate::mcp::SetEmissiveRequest { name, emissive },
                )
                .unwrap_or_else(|error| error)
            }
            "set_parent" => {
                let Some(name) = operation.name else {
                    results.push(McpResponse::Error(
                        "set_parent requires 'name' field".to_string(),
                    ));
                    continue;
                };
                super::transform::mcp_set_parent(
                    world,
                    crate::mcp::SetParentRequest {
                        name,
                        parent: operation.parent,
                    },
                )
                .unwrap_or_else(|error| error)
            }
            "clear_scene" => super::entity::mcp_clear_scene(world),
            "list_entities" => {
                let names: Vec<String> = world.resources.entity_names.keys().cloned().collect();
                McpResponse::EntityList(names)
            }
            "query_entity" => {
                let Some(name) = operation.name else {
                    results.push(McpResponse::Error(
                        "query_entity requires 'name' field".to_string(),
                    ));
                    continue;
                };
                super::entity::mcp_query_entity(world, crate::mcp::QueryEntityRequest { name })
                    .unwrap_or_else(|error| error)
            }
            "set_atmosphere" => {
                let Some(atmosphere) = operation.atmosphere else {
                    results.push(McpResponse::Error(
                        "set_atmosphere requires 'atmosphere' field".to_string(),
                    ));
                    continue;
                };
                super::environment::mcp_set_atmosphere(
                    world,
                    crate::mcp::SetAtmosphereRequest { atmosphere },
                )
            }
            _ => McpResponse::Error(format!(
                "Unknown operation '{}'. Valid operations: spawn_entity, despawn_entity, set_position, set_rotation, set_scale, set_material_color, set_emissive, set_parent, query_entity, list_entities, clear_scene, set_atmosphere",
                operation.operation
            )),
        };
        results.push(response);
    }

    results
}

fn parse_vec3(s: &str) -> Option<[f32; 3]> {
    let parts: Vec<&str> = s.split(',').collect();
    if parts.len() == 1 {
        let v = parts[0].parse().ok()?;
        Some([v, v, v])
    } else if parts.len() == 3 {
        Some([
            parts[0].parse().ok()?,
            parts[1].parse().ok()?,
            parts[2].parse().ok()?,
        ])
    } else {
        None
    }
}

fn parse_vec4(s: &str) -> Option<[f32; 4]> {
    let parts: Vec<&str> = s.split(',').collect();
    if parts.len() == 4 {
        Some([
            parts[0].parse().ok()?,
            parts[1].parse().ok()?,
            parts[2].parse().ok()?,
            parts[3].parse().ok()?,
        ])
    } else {
        None
    }
}

pub(crate) fn process_text_commands(world: &mut World, commands: &str) -> Vec<McpResponse> {
    let mut results = Vec::new();

    for line in commands.lines() {
        let line = line.trim();
        if line.is_empty() || line.starts_with('#') {
            continue;
        }

        let parts: Vec<&str> = line.split_whitespace().collect();
        if parts.is_empty() {
            continue;
        }

        let response = match parts[0].to_lowercase().as_str() {
            "spawn" | "s" => {
                if parts.len() < 4 {
                    McpResponse::Error(
                        "spawn requires: spawn <name> <mesh> <x>,<y>,<z> [options]".to_string(),
                    )
                } else {
                    let name = parts[1].to_string();
                    let mesh = parts[2].to_string();
                    let Some(position) = parse_vec3(parts[3]) else {
                        results.push(McpResponse::Error(format!(
                            "Invalid position '{}'. Use x,y,z format",
                            parts[3]
                        )));
                        continue;
                    };

                    let mut scale = [1.0, 1.0, 1.0];
                    let mut color = None;
                    let mut emissive = None;
                    let mut parent = None;
                    let mut alpha = None;

                    for part in &parts[4..] {
                        if let Some(val) = part
                            .strip_prefix("scale:")
                            .or_else(|| part.strip_prefix("sc:"))
                            .or_else(|| part.strip_prefix("s:"))
                        {
                            if let Some(s) = parse_vec3(val) {
                                scale = s;
                            }
                        } else if let Some(val) = part
                            .strip_prefix("color:")
                            .or_else(|| part.strip_prefix("c:"))
                        {
                            color = parse_vec4(val);
                        } else if let Some(val) = part
                            .strip_prefix("emissive:")
                            .or_else(|| part.strip_prefix("e:"))
                        {
                            emissive = parse_vec3(val);
                        } else if let Some(val) = part
                            .strip_prefix("parent:")
                            .or_else(|| part.strip_prefix("p:"))
                        {
                            parent = Some(val.to_string());
                        } else if let Some(val) = part
                            .strip_prefix("alpha:")
                            .or_else(|| part.strip_prefix("a:"))
                        {
                            alpha = Some(val.to_string());
                        }
                    }

                    super::entity::mcp_spawn_entity(
                        world,
                        crate::mcp::SpawnEntityRequest {
                            name,
                            mesh,
                            position,
                            scale: Some(scale),
                            color,
                            emissive,
                            parent,
                            alpha,
                        },
                    )
                }
            }
            "despawn" | "d" => {
                if parts.len() < 2 {
                    McpResponse::Error("despawn requires: despawn <name>".to_string())
                } else {
                    super::entity::mcp_despawn_entity(world, parts[1].to_string())
                }
            }
            "pos" | "position" => {
                if parts.len() < 3 {
                    McpResponse::Error("pos requires: pos <name> <x>,<y>,<z>".to_string())
                } else {
                    let Some(position) = parse_vec3(parts[2]) else {
                        results.push(McpResponse::Error(format!(
                            "Invalid position '{}'",
                            parts[2]
                        )));
                        continue;
                    };
                    super::transform::mcp_set_position(
                        world,
                        crate::mcp::SetPositionRequest {
                            name: parts[1].to_string(),
                            position,
                        },
                    )
                    .unwrap_or_else(|error| error)
                }
            }
            "rot" | "rotation" => {
                if parts.len() < 3 {
                    McpResponse::Error("rot requires: rot <name> <pitch>,<yaw>,<roll>".to_string())
                } else {
                    let Some(rotation) = parse_vec3(parts[2]) else {
                        results.push(McpResponse::Error(format!(
                            "Invalid rotation '{}'",
                            parts[2]
                        )));
                        continue;
                    };
                    super::transform::mcp_set_rotation(
                        world,
                        crate::mcp::SetRotationRequest {
                            name: parts[1].to_string(),
                            rotation,
                        },
                    )
                    .unwrap_or_else(|error| error)
                }
            }
            "scale" | "sc" => {
                if parts.len() < 3 {
                    McpResponse::Error("scale requires: scale <name> <x>,<y>,<z>".to_string())
                } else {
                    let Some(scale) = parse_vec3(parts[2]) else {
                        results.push(McpResponse::Error(format!("Invalid scale '{}'", parts[2])));
                        continue;
                    };
                    super::transform::mcp_set_scale(
                        world,
                        crate::mcp::SetScaleRequest {
                            name: parts[1].to_string(),
                            scale,
                        },
                    )
                    .unwrap_or_else(|error| error)
                }
            }
            "color" | "c" => {
                if parts.len() < 3 {
                    McpResponse::Error("color requires: color <name> <r>,<g>,<b>,<a>".to_string())
                } else {
                    let Some(color) = parse_vec4(parts[2]) else {
                        results.push(McpResponse::Error(format!("Invalid color '{}'", parts[2])));
                        continue;
                    };
                    super::material::mcp_set_material_color(
                        world,
                        crate::mcp::SetMaterialColorRequest {
                            name: parts[1].to_string(),
                            color,
                        },
                    )
                    .unwrap_or_else(|error| error)
                }
            }
            "emissive" | "e" => {
                if parts.len() < 3 {
                    McpResponse::Error("emissive requires: emissive <name> <r>,<g>,<b>".to_string())
                } else {
                    let Some(emissive) = parse_vec3(parts[2]) else {
                        results.push(McpResponse::Error(format!(
                            "Invalid emissive '{}'",
                            parts[2]
                        )));
                        continue;
                    };
                    super::material::mcp_set_emissive(
                        world,
                        crate::mcp::SetEmissiveRequest {
                            name: parts[1].to_string(),
                            emissive,
                        },
                    )
                    .unwrap_or_else(|error| error)
                }
            }
            "parent" | "p" => {
                if parts.len() < 3 {
                    McpResponse::Error("parent requires: parent <child> <parent>".to_string())
                } else {
                    super::transform::mcp_set_parent(
                        world,
                        crate::mcp::SetParentRequest {
                            name: parts[1].to_string(),
                            parent: Some(parts[2].to_string()),
                        },
                    )
                    .unwrap_or_else(|error| error)
                }
            }
            "unparent" => {
                if parts.len() < 2 {
                    McpResponse::Error("unparent requires: unparent <name>".to_string())
                } else {
                    super::transform::mcp_set_parent(
                        world,
                        crate::mcp::SetParentRequest {
                            name: parts[1].to_string(),
                            parent: None,
                        },
                    )
                    .unwrap_or_else(|error| error)
                }
            }
            "clear" | "clr" => super::entity::mcp_clear_scene(world),
            "list" | "ls" => {
                let names: Vec<String> = world.resources.entity_names.keys().cloned().collect();
                McpResponse::EntityList(names)
            }
            "query" | "q" => {
                if parts.len() < 2 {
                    McpResponse::Error("query requires: query <name>".to_string())
                } else {
                    super::entity::mcp_query_entity(
                        world,
                        crate::mcp::QueryEntityRequest {
                            name: parts[1].to_string(),
                        },
                    )
                    .unwrap_or_else(|error| error)
                }
            }
            "atmosphere" | "atmo" => {
                if parts.len() < 2 {
                    McpResponse::Error("atmosphere requires: atmosphere <type>".to_string())
                } else {
                    super::environment::mcp_set_atmosphere(
                        world,
                        crate::mcp::SetAtmosphereRequest {
                            atmosphere: parts[1].to_string(),
                        },
                    )
                }
            }
            "hdr" => {
                if parts.len() < 2 {
                    McpResponse::Error("hdr requires: hdr <path>".to_string())
                } else {
                    super::environment::mcp_load_hdr(
                        world,
                        crate::mcp::LoadHdrRequest {
                            path: parts[1].to_string(),
                        },
                    )
                }
            }
            _ => McpResponse::Error(format!(
                "Unknown command '{}'. Valid: s(pawn), d(espawn), pos, rot, sc(ale), c(olor), e(missive), p(arent), b(ehavior), clr/clear, ls/list, q(uery), atmo(sphere), hdr",
                parts[0]
            )),
        };
        results.push(response);
    }

    results
}
