use std::path::PathBuf;

use serde::Deserialize;

use crate::domain::plugin::{PluginId, PluginInfo, PluginStatus};

#[derive(Debug, Deserialize)]
pub struct PluginManifest {
    pub name: String,
    pub version: String,
    pub description: String,
    pub entry_point: String,
}

pub fn load_plugin_configs() -> Vec<PluginInfo> {
    let plugins_dir = match plugins_base_dir() {
        Some(p) => p,
        None => return vec![],
    };

    if !plugins_dir.exists() {
        return vec![];
    }

    let read_dir = match std::fs::read_dir(&plugins_dir) {
        Ok(d) => d,
        Err(_) => return vec![],
    };

    let mut plugins = Vec::new();

    for entry in read_dir.flatten() {
        let plugin_dir = entry.path();
        if !plugin_dir.is_dir() {
            continue;
        }

        let manifest_path = plugin_dir.join("plugin.json");
        if !manifest_path.exists() {
            continue;
        }

        let contents = match std::fs::read_to_string(&manifest_path) {
            Ok(c) => c,
            Err(_) => continue,
        };

        let manifest: PluginManifest = match serde_json::from_str(&contents) {
            Ok(m) => m,
            Err(_) => continue,
        };

        let id = entry.file_name().to_string_lossy().to_string();
        plugins.push(PluginInfo {
            id: PluginId::new(id),
            name: manifest.name,
            version: manifest.version,
            description: manifest.description,
            path: plugin_dir,
            status: PluginStatus::Installed,
        });
    }

    plugins
}

fn plugins_base_dir() -> Option<PathBuf> {
    stynx_code_config::home_dir()
        .map(|h| h.join(".claude").join("plugins"))
}
