agent-device-rec 0.1.0

Health device recommendation engine for longevity monitoring
use crate::catalog;
use crate::errors::DeviceError;
use crate::types::{ComparisonRow, DeviceCatalogFile, DeviceComparison};

/// Build a side-by-side comparison of two or more devices.
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();

    // Name
    matrix.push(ComparisonRow {
        attribute: "Name".to_string(),
        values: devices.iter().map(|d| d.name.clone()).collect(),
    });

    // Brand
    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(),
    });

    // Category
    matrix.push(ComparisonRow {
        attribute: "Category".to_string(),
        values: devices.iter().map(|d| d.category.clone()).collect(),
    });

    // Price
    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(),
    });

    // Connectivity
    matrix.push(ComparisonRow {
        attribute: "Connectivity".to_string(),
        values: devices
            .iter()
            .map(|d| d.connectivity.join(", "))
            .collect(),
    });

    // Platforms
    matrix.push(ComparisonRow {
        attribute: "Platforms".to_string(),
        values: devices.iter().map(|d| d.platforms.join(", ")).collect(),
    });

    // Tracked Metrics
    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(),
    });

    // Use Cases
    matrix.push(ComparisonRow {
        attribute: "Use Cases".to_string(),
        values: devices.iter().map(|d| d.use_cases.join(", ")).collect(),
    });

    // Prescription Required
    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(),
    });

    // Integrations
    matrix.push(ComparisonRow {
        attribute: "Integrations".to_string(),
        values: devices
            .iter()
            .map(|d| d.integrations.join(", "))
            .collect(),
    });

    Ok(DeviceComparison {
        devices,
        comparison_matrix: matrix,
    })
}