//! Dependency integration for Cargo and Node.js

// use std::collections::HashMap; // TODO: Will be used for dependency mapping
use std::fs;
use std::path::Path;

use anyhow::{anyhow, Result};
use serde_json::Value;

use crate::commands::feature::FeatureManifest;

pub struct DependencyIntegrator<'a> {
    project_root: &'a Path,
}

impl<'a> DependencyIntegrator<'a> {
    pub fn new(project_root: &'a Path) -> Self {
        Self { project_root }
    }

    pub fn integrate(&self, manifest: &FeatureManifest) -> Result<()> {
        println!("  📦 Integrating Cargo dependencies...");

        let cargo_toml = self.project_root.join("Cargo.toml");
        if !cargo_toml.exists() {
            return Err(anyhow!("No Cargo.toml found in project root"));
        }

        // Read existing Cargo.toml
        let content = fs::read_to_string(&cargo_toml)?;
        let mut cargo_data: toml::Value = toml::from_str(&content)?;

        // Ensure workspace.dependencies section exists
        if cargo_data.get("workspace").is_none() {
            cargo_data["workspace"] = toml::Value::Table(toml::map::Map::new());
        }
        if cargo_data["workspace"].get("dependencies").is_none() {
            cargo_data["workspace"]["dependencies"] = toml::Value::Table(toml::map::Map::new());
        }

        let workspace_deps = cargo_data["workspace"]["dependencies"]
            .as_table_mut()
            .unwrap();

        // Add workspace dependencies
        if let Some(deps) = &manifest.dependencies.workspace {
            for dep in deps {
                // Check if dependency already exists
                if !workspace_deps.contains_key(dep) {
                    // Add with workspace = true reference
                    workspace_deps.insert(dep.clone(), toml::Value::String("*".to_string()));
                    println!("    ✓ Added workspace dependency: {}", dep);
                } else {
                    println!("    ↪ Workspace dependency already exists: {}", dep);
                }
            }
        }

        // Add external dependencies
        if let Some(deps) = &manifest.dependencies.external {
            for dep_str in deps {
                // Parse dependency string (e.g., "ratatui = '0.29'")
                let parts: Vec<&str> = dep_str.split('=').map(|s| s.trim()).collect();
                if parts.len() == 2 {
                    let dep_name = parts[0].trim_matches('"');
                    let dep_version = parts[1].trim_matches(['\'', '"']);

                    if !workspace_deps.contains_key(dep_name) {
                        workspace_deps.insert(
                            dep_name.to_string(),
                            toml::Value::String(dep_version.to_string()),
                        );
                        println!(
                            "    ✓ Added external dependency: {} = {}",
                            dep_name, dep_version
                        );
                    } else {
                        println!("    ↪ External dependency already exists: {}", dep_name);
                    }
                }
            }
        }

        // Write updated Cargo.toml
        let updated_content = toml::to_string_pretty(&cargo_data)?;
        fs::write(&cargo_toml, updated_content)?;

        println!("    ✅ Cargo dependencies integrated successfully");
        Ok(())
    }
}

pub struct NodeIntegrator<'a> {
    project_root: &'a Path,
}

impl<'a> NodeIntegrator<'a> {
    pub fn new(project_root: &'a Path) -> Self {
        Self { project_root }
    }

    pub fn integrate(&self, _manifest: &FeatureManifest) -> Result<()> {
        println!("  📦 Integrating Node.js dependencies...");

        let package_json = self.project_root.join("package.json");
        if !package_json.exists() {
            println!("    ↪ No package.json found, skipping Node.js integration");
            return Ok(());
        }

        // Read existing package.json
        let content = fs::read_to_string(&package_json)?;
        let mut package_data: Value = serde_json::from_str(&content)?;

        // Ensure dependencies section exists
        if package_data.get("dependencies").is_none() {
            package_data["dependencies"] = Value::Object(serde_json::Map::new());
        }

        if let Some(_deps) = package_data["dependencies"].as_object_mut() {
            // Add node dependencies from feature manifest
            // This would be implemented based on the feature manifest structure
            println!("    ✅ Node.js dependencies integrated successfully");
        }

        // Write updated package.json
        let updated_content = serde_json::to_string_pretty(&package_data)?;
        fs::write(&package_json, updated_content)?;

        Ok(())
    }
}
