use serde_json::{json, Value};
use std::error::Error;
use uuid::Uuid;

/// Creates a JSON object representing a unit with specified attributes.
///
/// This function generates a unique identifier for the unit, accepts dynamic inputs for unit attributes, and constructs a JSON object compliant with a predefined schema. It is ideal for creating standardized unit representations in applications that manage different types of resources.
///
/// # Parameters
/// - `unit_name`: A `String` specifying the name of the unit (e.g., "pounds", "hours").
/// - `label`: A `String` used to describe the unit (e.g., "weight", "duration").
/// - `quantity`: An `f64` value representing the quantity of the unit.
/// - `general_type`: An optional `String` that categorizes the unit into a predefined type such as "agent", "time", "physical", "monetary", or "information".
/// - `description`: An optional `String` providing additional details about the purpose or nature of the unit.
///
/// # Returns
/// This function returns a `Result<Value, Box<dyn Error>>`:
/// - `Ok(Value)`: A `serde_json::Value` representing the unit if the operation is successful.
/// - `Err(Box<dyn Error>)`: An error boxed as a `dyn Error` if any part of the unit creation fails, such as JSON serialization errors or UUID generation issues.
///
/// # Examples
/// Basic usage:
///
/// ```
/// let unit = create_unit(
///     "hours".to_string(),
///     "work duration".to_string(),
///     40.0,
///     Some("time".to_string()),
///     Some("Total hours worked in a week".to_string())
/// ).unwrap();
///
/// println!("Created unit: {:?}", unit);
/// ```
///
/// # Errors
/// This function can return errors in scenarios such as failure to generate a UUID or problems during JSON value construction.
///
/// # Note
/// It is important to ensure that the input parameters comply with the expecte
pub fn create_unit (
    unit_name: String,
    label: String,
    quantity: Into<f64>,
    general_type: Option<String>,
    description: Option<String>,
) -> Result<Value, Box<dyn Error>> {

    let mut unit = json!({
        "unitName": unit_name,
        "label": label,
        "quantity": quantity
    });

    if let Some(gtype) = general_type{
        unit["generalType"] = gtype;
    }

    if let Some(desc) = description{
        unit["description"] = desc;
    }

    unit["id"] = json!(Uuid::new_v4().to_string());

    Ok(unit)
}


