use std::path::Path;
use serde_json::{Map, Value};
use crate::data;
use crate::output::{emit, CliError, Ctx};
pub fn list(dir: &Path, ctx: Ctx) -> Result<(), CliError> {
let data = data::load(dir, "customers")?;
let arr = data
.get("customers")
.cloned()
.unwrap_or(Value::Array(vec![]));
emit(ctx, &arr);
Ok(())
}
pub fn get(dir: &Path, ctx: Ctx, slug: &str) -> Result<(), CliError> {
let data = data::load(dir, "customers")?;
let customers = data
.get("customers")
.and_then(|v| v.as_array())
.cloned()
.unwrap_or_default();
for c in customers {
if c.get("slug").and_then(|v| v.as_str()) == Some(slug) {
let enriched = enrich(dir, &c)?;
emit(ctx, &enriched);
return Ok(());
}
}
Err(CliError::not_found(
format!("customer not found: {slug}"),
Some("try `liber customers list`".into()),
))
}
fn enrich(dir: &Path, customer: &Value) -> Result<Value, CliError> {
let mut out: Map<String, Value> = customer
.as_object()
.cloned()
.unwrap_or_default();
if let Some(related) = customer.get("related_products").and_then(|v| v.as_array()) {
if !related.is_empty() {
let products = data::load(dir, "products")?;
let arr = products
.get("products")
.and_then(|v| v.as_array())
.cloned()
.unwrap_or_default();
let wanted: Vec<&str> = related.iter().filter_map(|v| v.as_str()).collect();
let detail: Vec<Value> = arr
.into_iter()
.filter(|p| {
p.get("slug")
.and_then(|v| v.as_str())
.map(|s| wanted.contains(&s))
.unwrap_or(false)
})
.collect();
out.insert("products_detail".to_string(), Value::Array(detail));
}
}
if let Some(chats) = customer.get("chats").and_then(|v| v.as_array()) {
if !chats.is_empty() {
let chat_data = data::load(dir, "chats")?;
let map = chat_data
.get("group_chats")
.and_then(|v| v.as_object())
.cloned()
.unwrap_or_default();
let mut chat_ids = Map::new();
for c in chats {
if let Some(name) = c.as_str() {
let val = map.get(name).cloned().unwrap_or(Value::Null);
let id_val = match &val {
Value::Object(o) => o.get("id").cloned().unwrap_or(Value::Null),
_ => val,
};
chat_ids.insert(name.to_string(), id_val);
}
}
out.insert("chat_ids".to_string(), Value::Object(chat_ids));
}
}
Ok(Value::Object(out))
}