//! Types for project initialization
//!
//! Domain types used during project initialization. These types are shared
//! between handlers and services to maintain consistent data structures.

/// Template types for robot projects
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TemplateType {
    /// Minimal project with basic pub/sub
    Basic,
    /// Mobile robot with differential drive
    Rover,
    /// Robotic arm with joint control
    Arm,
    /// Bipedal robot
    Humanoid,
}

impl TemplateType {
    /// Get template ID as string
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Basic => "basic",
            Self::Rover => "rover",
            Self::Arm => "arm",
            Self::Humanoid => "humanoid",
        }
    }

    /// Parse template from string ID
    pub fn from_str(s: &str) -> Option<Self> {
        match s.to_lowercase().as_str() {
            "basic" => Some(Self::Basic),
            "rover" => Some(Self::Rover),
            "arm" => Some(Self::Arm),
            "humanoid" => Some(Self::Humanoid),
            _ => None,
        }
    }

    /// Get display name
    pub fn display_name(&self) -> &'static str {
        match self {
            Self::Basic => "Basic",
            Self::Rover => "Rover",
            Self::Arm => "Robotic Arm",
            Self::Humanoid => "Humanoid",
        }
    }

    /// Get template description
    pub fn description(&self) -> &'static str {
        match self {
            Self::Basic => "Minimal robot project with pub/sub messaging",
            Self::Rover => "Mobile robot with differential drive and sensors",
            Self::Arm => "Manipulator robot with joint control",
            Self::Humanoid => "Bipedal robot with full-body control",
        }
    }
}

/// Node selection for project initialization
#[allow(dead_code)] // Tested, planned for future use
#[derive(Debug, Clone)]
pub struct NodeSelection {
    /// Node ID (e.g., "speaker", "listener")
    pub id: String,
    /// Whether this node is selected
    pub selected: bool,
}

#[allow(dead_code)] // Tested, planned for future use
impl NodeSelection {
    /// Create a new node selection
    pub fn new(id: impl Into<String>, selected: bool) -> Self {
        Self {
            id: id.into(),
            selected,
        }
    }
}

/// Project configuration for initialization
///
/// This is the domain model for a project being initialized,
/// distinct from the runtime ProjectConfig in config_types.
#[allow(dead_code)] // Tested, planned for future use
#[derive(Debug, Clone)]
pub struct ProjectConfig {
    /// Project name
    pub name: String,
    /// Template type
    pub template: TemplateType,
    /// Selected nodes to include
    pub nodes: Vec<String>,
    /// Enable framework development mode
    pub dev_mode: bool,
    /// Skip simulation generation
    pub skip_sim: bool,
}

#[allow(dead_code)] // Tested, planned for future use
impl ProjectConfig {
    /// Create a new project configuration
    pub fn new(name: impl Into<String>, template: TemplateType) -> Self {
        Self {
            name: name.into(),
            template,
            nodes: Vec::new(),
            dev_mode: false,
            skip_sim: false,
        }
    }

    /// Add a node to the configuration
    pub fn with_node(mut self, node_id: impl Into<String>) -> Self {
        self.nodes.push(node_id.into());
        self
    }

    /// Set multiple nodes
    pub fn with_nodes(mut self, nodes: Vec<String>) -> Self {
        self.nodes = nodes;
        self
    }

    /// Enable development mode
    pub fn with_dev_mode(mut self, enabled: bool) -> Self {
        self.dev_mode = enabled;
        self
    }

    /// Skip simulation generation
    pub fn with_skip_sim(mut self, skip: bool) -> Self {
        self.skip_sim = skip;
        self
    }
}
