use crate::{
    invocation::{SkillContext, SkillInput},
    outcome::SkillOutcome,
    skill::{Skill, SkillId},
};
use prism::{index::ProjectIndex, search::lexical_search};
use serde_json::json;

pub struct CompassSkill;

impl Skill for CompassSkill {
    fn id(&self) -> SkillId {
        SkillId("compass")
    }
    fn display_name(&self) -> &str {
        "Compass"
    }

    fn input_schema(&self) -> serde_json::Value {
        json!({ "type": "object", "properties": { "query": { "type": "string" }, "root": { "type": "string" }, "top_k": { "type": "integer", "default": 10 } }, "required": ["query"] })
    }

    fn output_schema(&self) -> serde_json::Value {
        json!({ "type": "object", "properties": { "results": { "type": "array" }, "total_candidates": { "type": "integer" } } })
    }

    fn execute(&self, input: SkillInput, _ctx: &SkillContext) -> anyhow::Result<SkillOutcome> {
        let query = input.get_str("query").unwrap_or("").to_string();
        let root = input.get_str("root").unwrap_or(".").to_string();
        let top_k = input.get_u64("top_k").unwrap_or(10) as usize;

        let index_path = std::path::Path::new(&root).join(".bctx").join("index.json");
        let index = if index_path.exists() {
            let json = std::fs::read_to_string(&index_path).unwrap_or_default();
            serde_json::from_str::<ProjectIndex>(&json).unwrap_or_else(|_| ProjectIndex::new(&root))
        } else {
            ProjectIndex::new(&root)
        };

        let results = lexical_search(&index, &query, top_k);
        let result_json: Vec<serde_json::Value> = results
            .iter()
            .map(|r| {
                json!({
                    "path": r.path,
                    "symbol": r.symbol,
                    "snippet": r.snippet,
                    "score": r.score
                })
            })
            .collect();

        Ok(SkillOutcome::success(
            "compass",
            json!({ "results": result_json, "total_candidates": result_json.len() }),
        ))
    }
}
