//! Device registry domain logic — register, list, revoke devices.

use std::sync::Arc;

use crate::storage::Store;

use super::types::*;

const MAX_DEVICES_PER_IDENTITY: usize = 5;

/// Domain service for multi-device management.
pub struct DeviceService {
    pub store: Arc<dyn Store>,
}

impl DeviceService {
    pub fn register_device(
        &self,
        req: RegisterDeviceReq,
        caller_identity_key: &[u8],
    ) -> Result<RegisterDeviceResp, DomainError> {
        if req.device_id.is_empty() {
            return Err(DomainError::BadParams(
                "device_id must not be empty".into(),
            ));
        }

        let count = self.store.device_count(caller_identity_key)?;
        if count >= MAX_DEVICES_PER_IDENTITY {
            return Err(DomainError::DeviceLimit(MAX_DEVICES_PER_IDENTITY));
        }

        let success =
            self.store
                .register_device(caller_identity_key, &req.device_id, &req.device_name)?;

        Ok(RegisterDeviceResp { success })
    }

    pub fn list_devices(
        &self,
        caller_identity_key: &[u8],
    ) -> Result<ListDevicesResp, DomainError> {
        let raw = self.store.list_devices(caller_identity_key)?;
        let devices = raw
            .into_iter()
            .map(|(device_id, device_name, registered_at)| DeviceInfo {
                device_id,
                device_name,
                registered_at,
            })
            .collect();
        Ok(ListDevicesResp { devices })
    }

    pub fn revoke_device(
        &self,
        req: RevokeDeviceReq,
        caller_identity_key: &[u8],
    ) -> Result<RevokeDeviceResp, DomainError> {
        if req.device_id.is_empty() {
            return Err(DomainError::BadParams(
                "device_id must not be empty".into(),
            ));
        }

        let success = self
            .store
            .revoke_device(caller_identity_key, &req.device_id)?;
        if !success {
            return Err(DomainError::DeviceNotFound);
        }

        Ok(RevokeDeviceResp { success })
    }
}
