use crate::catalog;
use crate::errors::DeviceError;
use crate::types::{ComparisonRow, DeviceCatalogFile, DeviceComparison};
pub fn compare_devices(
catalog: &DeviceCatalogFile,
device_ids: &[String],
) -> Result<DeviceComparison, DeviceError> {
if device_ids.len() < 2 {
return Err(DeviceError::InvalidInput(
"Compare requires at least 2 device IDs".into(),
));
}
let mut devices = Vec::new();
for id in device_ids {
let device = catalog::find_device(catalog, id)
.ok_or_else(|| DeviceError::DeviceNotFound(id.clone()))?;
devices.push(device.clone());
}
let mut matrix = Vec::new();
matrix.push(ComparisonRow {
attribute: "Name".to_string(),
values: devices.iter().map(|d| d.name.clone()).collect(),
});
matrix.push(ComparisonRow {
attribute: "Brand".to_string(),
values: devices
.iter()
.map(|d| {
catalog::find_brand(catalog, &d.brand_id)
.map(|b| b.name.clone())
.unwrap_or_else(|| d.brand_id.clone())
})
.collect(),
});
matrix.push(ComparisonRow {
attribute: "Category".to_string(),
values: devices.iter().map(|d| d.category.clone()).collect(),
});
matrix.push(ComparisonRow {
attribute: "Price".to_string(),
values: devices
.iter()
.map(|d| {
d.price_usd
.map(|p| format!("${p} ({})", d.price_range))
.unwrap_or_else(|| d.price_range.clone())
})
.collect(),
});
matrix.push(ComparisonRow {
attribute: "Connectivity".to_string(),
values: devices
.iter()
.map(|d| d.connectivity.join(", "))
.collect(),
});
matrix.push(ComparisonRow {
attribute: "Platforms".to_string(),
values: devices.iter().map(|d| d.platforms.join(", ")).collect(),
});
matrix.push(ComparisonRow {
attribute: "Tracked Metrics".to_string(),
values: devices
.iter()
.map(|d| {
d.tracks
.iter()
.map(|t| format!("{} ({})", t.metric, t.accuracy))
.collect::<Vec<_>>()
.join(", ")
})
.collect(),
});
matrix.push(ComparisonRow {
attribute: "Use Cases".to_string(),
values: devices.iter().map(|d| d.use_cases.join(", ")).collect(),
});
matrix.push(ComparisonRow {
attribute: "Prescription Required".to_string(),
values: devices
.iter()
.map(|d| {
if d.prescription_required {
"Yes".to_string()
} else {
"No".to_string()
}
})
.collect(),
});
matrix.push(ComparisonRow {
attribute: "Integrations".to_string(),
values: devices
.iter()
.map(|d| d.integrations.join(", "))
.collect(),
});
Ok(DeviceComparison {
devices,
comparison_matrix: matrix,
})
}