//! Feature registry client

use std::path::PathBuf;

use rustelo_core::Result;
use tokio::fs;

use super::*;

pub struct FeatureRegistry {
    client: MarketplaceClient,
    cache_path: PathBuf,
}

impl FeatureRegistry {
    pub fn new(config: MarketplaceConfig) -> Self {
        let cache_path = shellexpand::tilde(&config.cache_path).into_owned().into();
        Self {
            client: MarketplaceClient::new(config),
            cache_path,
        }
    }

    pub async fn search(&self, query: &str) -> Result<Vec<FeaturePackage>> {
        self.client.search_features(query).await
    }

    pub async fn install(&self, name: &str, version: Option<&str>) -> Result<()> {
        println!("📦 Installing feature: {}", name);

        // Get feature package info
        let package = self.client.get_feature(name, version).await?;

        // Verify integrity
        self.verify_package(&package).await?;

        // Download feature
        let data = self.client.download_feature(&package).await?;

        // Extract to cache
        let cache_dir = self.cache_path.join(&package.name).join(&package.version);
        fs::create_dir_all(&cache_dir).await?;

        // Extract archive (assuming tar.gz)
        let archive_path = cache_dir.join("package.tar.gz");
        fs::write(&archive_path, data).await?;

        // Extract archive
        self.extract_archive(&archive_path, &cache_dir).await?;

        println!("✅ Feature \'{}\' installed successfully", name);
        Ok(())
    }

    pub async fn list_installed(&self) -> Result<Vec<String>> {
        let mut features = Vec::new();
        if self.cache_path.exists() {
            let mut entries = fs::read_dir(&self.cache_path).await?;
            while let Some(entry) = entries.next_entry().await? {
                if entry.file_type().await?.is_dir() {
                    if let Some(name) = entry.file_name().to_str() {
                        features.push(name.to_string());
                    }
                }
            }
        }
        Ok(features)
    }

    pub async fn uninstall(&self, name: &str) -> Result<()> {
        let feature_path = self.cache_path.join(name);
        if feature_path.exists() {
            fs::remove_dir_all(feature_path).await?;
            println!("✅ Feature \'{}\' uninstalled", name);
        } else {
            println!("⚠️  Feature \'{}\' not found", name);
        }
        Ok(())
    }

    async fn verify_package(&self, _package: &FeaturePackage) -> Result<()> {
        // TODO: Implement signature verification
        println!("🔐 Verifying package integrity...");
        Ok(())
    }

    async fn extract_archive(&self, _archive_path: &PathBuf, _dest: &PathBuf) -> Result<()> {
        // TODO: Implement archive extraction
        println!("📂 Extracting package...");
        Ok(())
    }
}
