use crate::ConfigEasyError;

/// A callback used to perform a custom action when a specific menu key is entered.
pub type MenuActionCallback<'a> =
    dyn Fn(&rusqlite::Connection) -> Result<(), Box<dyn std::error::Error + Send + Sync>> + 'a;

/// Represents a custom action that can be triggered from the configuration menu by entering a specific key.    
pub struct MenuAction<'a> {
    pub(crate) key: String,
    pub(crate) label: String,
    pub(crate) callback: Box<MenuActionCallback<'a>>,
}

/// Validates that a given action key is valid and not reserved for exiting the menu.
/// An action key is considered valid if it is not empty, does not consist solely of digits, and is not "q" or "quit" (case-sensitive).
/// If the key is invalid or reserved, an appropriate error is returned.
///
/// # Arguments
/// * `key` - The action key to validate.
///
/// # Returns
/// A `Result` indicating whether the action key is valid or if an error occurred.
pub(crate) fn validate_action_key(key: &str) -> Result<(), ConfigEasyError> {
    if key.is_empty() || key.chars().all(|ch| ch.is_ascii_digit()) {
        return Err(ConfigEasyError::InvalidActionKey(key.to_string()));
    }

    if key == "q" || key == "quit" {
        return Err(ConfigEasyError::ReservedActionKey(key.to_string()));
    }

    Ok(())
}

#[cfg(test)]
mod tests;
