use std::collections::HashMap;

use serde_json::json;

use crate::protocol::{JsonSchema, ToolDefinition};

pub struct ToolRegistry {
    tools: HashMap<String, ToolDefinition>,
}

impl ToolRegistry {
    pub fn new() -> Self {
        let mut tools = HashMap::new();

        tools.insert(
            "kanban_create_task".to_string(),
            ToolDefinition {
                name: "kanban_create_task".to_string(),
                description: "Create a new task in the Kanban board".to_string(),
                input_schema: JsonSchema {
                    schema_type: "object".to_string(),
                    properties: [
                        ("project_id".to_string(), json!({ "type": "string" })),
                        ("title".to_string(), json!({ "type": "string" })),
                        ("description".to_string(), json!({ "type": "string" })),
                        (
                            "priority".to_string(),
                            json!({
                                "type": "string",
                                "enum": ["low", "medium", "high", "critical"]
                            }),
                        ),
                    ]
                    .into_iter()
                    .collect(),
                    required: vec!["project_id".to_string(), "title".to_string()],
                },
            },
        );

        tools.insert(
            "kanban_update_task".to_string(),
            ToolDefinition {
                name: "kanban_update_task".to_string(),
                description: "Update task status".to_string(),
                input_schema: JsonSchema {
                    schema_type: "object".to_string(),
                    properties: [
                        ("task_id".to_string(), json!({ "type": "string" })),
                        (
                            "status".to_string(),
                            json!({
                                "type": "string",
                                "enum": ["todo", "doing", "review", "done"]
                            }),
                        ),
                    ]
                    .into_iter()
                    .collect(),
                    required: vec!["task_id".to_string(), "status".to_string()],
                },
            },
        );

        tools.insert(
            "get_project_summary".to_string(),
            ToolDefinition {
                name: "get_project_summary".to_string(),
                description: "Get project summary and statistics".to_string(),
                input_schema: JsonSchema {
                    schema_type: "object".to_string(),
                    properties: [("project_id".to_string(), json!({ "type": "string" }))]
                        .into_iter()
                        .collect(),
                    required: vec!["project_id".to_string()],
                },
            },
        );

        tools.insert(
            "list_agents".to_string(),
            ToolDefinition {
                name: "list_agents".to_string(),
                description: "List all available agents".to_string(),
                input_schema: JsonSchema {
                    schema_type: "object".to_string(),
                    properties: HashMap::new(),
                    required: Vec::new(),
                },
            },
        );

        tools.insert(
            "get_agent_capabilities".to_string(),
            ToolDefinition {
                name: "get_agent_capabilities".to_string(),
                description: "Get agent capabilities".to_string(),
                input_schema: JsonSchema {
                    schema_type: "object".to_string(),
                    properties: [("agent_id".to_string(), json!({ "type": "string" }))]
                        .into_iter()
                        .collect(),
                    required: vec!["agent_id".to_string()],
                },
            },
        );

        tools.insert(
            "assign_task_to_agent".to_string(),
            ToolDefinition {
                name: "assign_task_to_agent".to_string(),
                description: "Assign a task to an agent".to_string(),
                input_schema: JsonSchema {
                    schema_type: "object".to_string(),
                    properties: [
                        ("role".to_string(), json!({ "type": "string" })),
                        ("task_title".to_string(), json!({ "type": "string" })),
                        ("task_description".to_string(), json!({ "type": "string" })),
                    ]
                    .into_iter()
                    .collect(),
                    required: vec![
                        "role".to_string(),
                        "task_title".to_string(),
                        "task_description".to_string(),
                    ],
                },
            },
        );

        Self { tools }
    }

    #[allow(dead_code)]
    pub fn get(&self, name: &str) -> Option<&ToolDefinition> {
        self.tools.get(name)
    }

    pub fn list(&self) -> Vec<ToolDefinition> {
        self.tools.values().cloned().collect()
    }
}

impl Default for ToolRegistry {
    fn default() -> Self {
        Self::new()
    }
}
