/// Add command — install components from the DreamStack registry.

use std::fs;
use std::path::Path;

struct RegistryItem {
    name: &'static str,
    description: &'static str,
    source: &'static str,
    deps: &'static [&'static str],
}

const REGISTRY: &[RegistryItem] = &[
    RegistryItem {
        name: "button",
        description: "Styled button with variant support (primary, secondary, ghost, destructive)",
        source: include_str!("../../../../registry/components/button.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "input",
        description: "Text input with label, placeholder, and error state",
        source: include_str!("../../../../registry/components/input.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "card",
        description: "Content container with title and styled border",
        source: include_str!("../../../../registry/components/card.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "badge",
        description: "Status badge with color variants",
        source: include_str!("../../../../registry/components/badge.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "dialog",
        description: "Modal dialog with overlay and close button",
        source: include_str!("../../../../registry/components/dialog.ds"),
        deps: &["button"],
    },
    RegistryItem {
        name: "toast",
        description: "Notification toast with auto-dismiss",
        source: include_str!("../../../../registry/components/toast.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "progress",
        description: "Animated progress bar with percentage",
        source: include_str!("../../../../registry/components/progress.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "alert",
        description: "Alert banner with info/warning/error/success variants",
        source: include_str!("../../../../registry/components/alert.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "separator",
        description: "Visual divider between content sections",
        source: include_str!("../../../../registry/components/separator.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "toggle",
        description: "On/off switch toggle",
        source: include_str!("../../../../registry/components/toggle.ds"),
        deps: &[],
    },
    RegistryItem {
        name: "avatar",
        description: "User avatar with initials fallback",
        source: include_str!("../../../../registry/components/avatar.ds"),
        deps: &[],
    },
];

pub fn cmd_add(name: Option<String>, list: bool, all: bool) {
    if list {
        println!("📦 Available DreamStack components:\n");
        for item in REGISTRY {
            let deps = if item.deps.is_empty() {
                String::new()
            } else {
                format!(" (deps: {})", item.deps.join(", "))
            };
            println!("   {} — {}{}", item.name, item.description, deps);
        }
        println!("\n   Use: dreamstack add <name>");
        return;
    }

    let components_dir = Path::new("components");
    if !components_dir.exists() {
        fs::create_dir_all(components_dir).expect("Failed to create components/ directory");
    }

    let names_to_add: Vec<String> = if all {
        REGISTRY.iter().map(|r| r.name.to_string()).collect()
    } else if let Some(name) = name {
        vec![name]
    } else {
        println!("Usage: dreamstack add <component>\n       dreamstack add --list\n       dreamstack add --all");
        return;
    };

    let mut added = std::collections::HashSet::new();
    for name in &names_to_add {
        add_component(name, components_dir, &mut added);
    }

    if added.is_empty() {
        println!("❌ No components found. Use 'dreamstack add --list' to see available.");
    }
}

fn add_component(name: &str, dest: &Path, added: &mut std::collections::HashSet<String>) {
    if added.contains(name) {
        return;
    }

    let item = match REGISTRY.iter().find(|r| r.name == name) {
        Some(item) => item,
        None => {
            println!("   ❌ Unknown component: {name}");
            return;
        }
    };

    // Add dependencies first
    for dep in item.deps {
        add_component(dep, dest, added);
    }

    let dest_file = dest.join(format!("{}.ds", name));
    // Fix imports: ./button → ./button (relative within components/)
    let source = item.source.replace("from \"./", "from \"./");
    fs::write(&dest_file, source).expect("Failed to write component file");

    let dep_info = if !item.deps.is_empty() {
        " (dependency)"
    } else {
        ""
    };
    println!("   ✅ Added components/{}.ds{}", name, dep_info);
    added.insert(name.to_string());
}

/// Get registry for use by init command.
pub fn get_registry_source(name: &str) -> Option<&'static str> {
    REGISTRY.iter().find(|r| r.name == name).map(|r| r.source)
}
