//! Interactive project selection using inquire
//!
//! Provides a terminal UI for selecting projects when auto-detection is not possible.
//! Uses arrow keys for navigation (requires "interactive" feature).
//!
//! # Features
//! Requires the "interactive" feature to be enabled:
//!
//! ```toml
//! [dependencies]
//! tools-shared = { version = "0.1", features = ["interactive"] }
//! ```
//!
//! # Examples
//! ```no_run
//! use tools_shared::{select_project, SelectableProject};
//!
//! let projects = vec![
//!     SelectableProject {
//!         id: "my-project".to_string(),
//!         name: "My Project".to_string(),
//!         path: Some("/Users/akasha/my-project".to_string()),
//!         metadata: Some("Phase: Devel".to_string()),
//!     },
//! ];
//!
//! let selected = select_project(projects, "Select a project:", None)?;
//! println!("Selected: {}", selected);
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```

/// Project information for interactive selection
#[derive(Debug, Clone)]
pub struct SelectableProject {
    /// Project ID (used internally)
    pub id: String,
    /// Display name
    pub name: String,
    /// Optional project path
    pub path: Option<String>,
    /// Optional metadata (e.g., "Phase: Devel")
    pub metadata: Option<String>,
}

#[cfg(feature = "interactive")]
/// Show interactive project selector using inquire
///
/// Displays projects with arrow key navigation and returns selected project ID.
///
/// # Arguments
/// * `projects` - List of selectable projects
/// * `prompt` - Prompt text to display
/// * `default_id` - Optional default project ID (pre-selected)
///
/// # Returns
/// Selected project ID
///
/// # Errors
/// Returns error if user cancels selection or inquire fails
///
/// # Examples
/// ```no_run
/// use tools_shared::{select_project, SelectableProject};
///
/// let projects = vec![
///     SelectableProject {
///         id: "proj1".to_string(),
///         name: "Project 1".to_string(),
///         path: Some("/path/to/proj1".to_string()),
///         metadata: None,
///     },
/// ];
///
/// let selected = select_project(projects, "Choose project:", None)?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
pub fn select_project(
    projects: Vec<SelectableProject>,
    prompt: &str,
    default_id: Option<&str>,
) -> Result<String, Box<dyn std::error::Error>> {
    use inquire::Select;

    if projects.is_empty() {
        return Err("No projects available".into());
    }

    // Format options for display
    let options: Vec<String> = projects.iter().map(format_project_option).collect();

    // Find default index
    let default_index = default_id
        .and_then(|id| projects.iter().position(|p| p.id == id))
        .unwrap_or(0);

    // Show selector
    let selection = Select::new(prompt, options)
        .with_starting_cursor(default_index)
        .prompt()?;

    // Find and return the ID of selected project
    let selected_name = selection.split(" • ").next().unwrap_or(&selection);
    let selected_project = projects
        .iter()
        .find(|p| p.name == selected_name)
        .ok_or("Project not found")?;

    Ok(selected_project.id.clone())
}

/// Format project for display in selector
///
/// Creates a readable option string with project name, path, and metadata.
///
/// # Examples
/// ```
/// use tools_shared::{format_project_option, SelectableProject};
///
/// let project = SelectableProject {
///     id: "proj1".to_string(),
///     name: "My Project".to_string(),
///     path: Some("/home/user/my-project".to_string()),
///     metadata: Some("Phase: Devel".to_string()),
/// };
///
/// let formatted = format_project_option(&project);
/// assert!(formatted.contains("My Project"));
/// ```
pub fn format_project_option(project: &SelectableProject) -> String {
    let mut parts = vec![project.name.clone()];

    if let Some(ref path) = project.path {
        parts.push(format!("({})", path));
    }

    if let Some(ref metadata) = project.metadata {
        parts.push(metadata.clone());
    }

    parts.join(" • ")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_format_project_option_full() {
        let project = SelectableProject {
            id: "proj1".to_string(),
            name: "My Project".to_string(),
            path: Some("/home/user/project".to_string()),
            metadata: Some("Phase: Devel".to_string()),
        };

        let formatted = format_project_option(&project);
        assert!(formatted.contains("My Project"));
        assert!(formatted.contains("/home/user/project"));
        assert!(formatted.contains("Phase: Devel"));
        assert!(formatted.contains("•"));
    }

    #[test]
    fn test_format_project_option_minimal() {
        let project = SelectableProject {
            id: "proj1".to_string(),
            name: "My Project".to_string(),
            path: None,
            metadata: None,
        };

        let formatted = format_project_option(&project);
        assert_eq!(formatted, "My Project");
    }

    #[test]
    fn test_format_project_option_with_metadata() {
        let project = SelectableProject {
            id: "proj1".to_string(),
            name: "My Project".to_string(),
            path: None,
            metadata: Some("Status: Active".to_string()),
        };

        let formatted = format_project_option(&project);
        assert!(formatted.contains("My Project"));
        assert!(formatted.contains("Status: Active"));
    }

    #[test]
    #[cfg(feature = "interactive")]
    fn test_select_project_error_on_empty() {
        let result = select_project(vec![], "Select project:", None);
        assert!(result.is_err());
    }
}
