use serde::Deserialize;

use crate::error::Error;

#[derive(Debug, Clone, Deserialize)]
pub struct Device {
    pub id: String,
    pub device_type: String,
    #[serde(default)]
    pub platform: Option<String>,
    #[serde(default)]
    pub name: Option<String>,
    #[serde(default)]
    pub app_version: Option<String>,
    pub activated_at: String,
    #[serde(default)]
    pub last_seen_at: Option<String>,
    #[serde(default)]
    pub revoked_at: Option<String>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct DevicesPage {
    pub slots_used: u32,
    pub slots_limit: u32,
    #[serde(default)]
    pub devices: Vec<Device>,
}

#[derive(Debug, Clone, Default, Deserialize)]
pub struct DeviceLimitInfo {
    #[serde(default)]
    pub code: String,
    #[serde(default)]
    pub message: String,
    #[serde(default)]
    pub slots_limit: u32,
    #[serde(default)]
    pub slots_used: u32,
    #[serde(default)]
    pub devices: Vec<Device>,
}

/// Extracts device-limit details from a failed activation. Returns `None` unless
/// the error is a 409 `device_limit_reached` response carrying the slot counts
/// and the customer's registered devices.
pub fn device_limit_from_error(err: &Error) -> Option<DeviceLimitInfo> {
    match err {
        Error::Api { code, body, .. } if code == "device_limit_reached" => Some(
            body.as_ref()
                .and_then(|b| serde_json::from_value(b.clone()).ok())
                .unwrap_or_default(),
        ),
        _ => None,
    }
}
