//! Public MCP template tools.
//!
//! The MCP surface exposes global agent templates without adding them to the
//! orchestration command enum. A driving adapter injects the provider that maps
//! these calls to the application template use cases.

use async_trait::async_trait;
use domain::Project;
use serde_json::{json, Value};

use super::tools::ToolDef;

/// Error returned by an MCP template tool provider.
#[derive(Debug, Clone, thiserror::Error)]
#[error("{code}: {message}")]
pub struct TemplateToolError {
    /// Stable machine-readable code.
    pub code: &'static str,
    /// Human-readable message.
    pub message: String,
}

impl TemplateToolError {
    /// Builds a typed template-tool error.
    #[must_use]
    pub fn new(code: &'static str, message: impl Into<String>) -> Self {
        Self {
            code,
            message: message.into(),
        }
    }

    /// Serialises the error as a camelCase JSON object.
    #[must_use]
    pub fn to_value(&self) -> Value {
        json!({ "code": self.code, "message": self.message })
    }
}

/// Provider injected by the composition root to execute public template tools.
#[async_trait]
pub trait TemplateToolProvider: Send + Sync {
    /// Executes one public template tool.
    async fn handle_template_tool(
        &self,
        project: &Project,
        requester: &str,
        name: &str,
        arguments: Value,
    ) -> Result<Value, TemplateToolError>;
}

/// Returns true when `name` is one of the public template tools.
#[must_use]
pub fn is_template_tool(name: &str) -> bool {
    matches!(
        name,
        "idea_template_list"
            | "idea_template_read"
            | "idea_template_create"
            | "idea_template_update"
            | "idea_template_delete"
    )
}

/// Public template tool definitions advertised by `tools/list`.
#[must_use]
pub fn catalogue() -> Vec<ToolDef> {
    let template_id = json!({ "type": "string", "format": "uuid" });

    vec![
        ToolDef {
            name: "idea_template_list",
            description: "List global IdeA agent templates.",
            input_schema: json!({
                "type": "object",
                "properties": {},
                "additionalProperties": false
            }),
        },
        ToolDef {
            name: "idea_template_read",
            description: "Read one global IdeA agent template by id.",
            input_schema: json!({
                "type": "object",
                "properties": {
                    "templateId": template_id.clone()
                },
                "required": ["templateId"],
                "additionalProperties": false
            }),
        },
        ToolDef {
            name: "idea_template_create",
            description: "Create a global IdeA agent template.",
            input_schema: json!({
                "type": "object",
                "properties": {
                    "name": { "type": "string" },
                    "content": { "type": "string" },
                    "defaultProfileId": { "type": "string", "format": "uuid" }
                },
                "required": ["name", "content", "defaultProfileId"],
                "additionalProperties": false
            }),
        },
        ToolDef {
            name: "idea_template_update",
            description: "Update a global IdeA agent template's Markdown content.",
            input_schema: json!({
                "type": "object",
                "properties": {
                    "templateId": template_id.clone(),
                    "content": { "type": "string" }
                },
                "required": ["templateId", "content"],
                "additionalProperties": false
            }),
        },
        ToolDef {
            name: "idea_template_delete",
            description: "Delete a global IdeA agent template.",
            input_schema: json!({
                "type": "object",
                "properties": {
                    "templateId": template_id
                },
                "required": ["templateId"],
                "additionalProperties": false
            }),
        },
    ]
}
