use std::sync::Arc;

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

use crate::health::HealthService;
use crate::tools::{Tool, ToolResult};

pub struct HealthTool {
    health: Arc<HealthService>,
}

impl HealthTool {
    pub fn new(health: Arc<HealthService>) -> Self {
        Self { health }
    }
}

#[async_trait]
impl Tool for HealthTool {
    fn name(&self) -> &str {
        "health"
    }

    fn description(&self) -> &str {
        "Check PicoBot runtime dependencies without changing the system. Reports required, configuration-dependent, and optional components with remediation guidance."
    }

    fn parameters_schema(&self) -> Value {
        json!({
            "type": "object",
            "properties": {
                "json": {
                    "type": "boolean",
                    "description": "Return the structured health report as JSON instead of text"
                }
            }
        })
    }

    fn read_only(&self) -> bool {
        true
    }

    async fn execute(&self, args: Value) -> anyhow::Result<ToolResult> {
        let report = self.health.check().await;
        let output = if args.get("json").and_then(Value::as_bool).unwrap_or(false) {
            serde_json::to_string_pretty(&report)?
        } else {
            report.render_text()
        };
        Ok(ToolResult {
            success: true,
            output,
            error: None,
        })
    }
}
