import 'dart:developer'; import 'package:syncrow_web/services/api/http_service.dart'; import 'package:syncrow_web/utils/constants/api_const.dart'; abstract interface class BatchControlDevicesService { Future batchControlDevices({ required List uuids, required String code, required Object value, }); } final class RemoteBatchControlDevicesService implements BatchControlDevicesService { @override Future batchControlDevices({ required List uuids, required String code, required Object value, }) async { try { final body = { 'devicesUuid': uuids, 'code': code, 'value': value, 'operationType': 'COMMAND', }; final response = await HTTPService().post( path: ApiEndpoints.deviceBatchControl, body: body, showServerMessage: true, expectedResponseModel: (json) => (json['success'] as bool?) ?? false, ); return response; } catch (e) { log('Error fetching $e', name: 'BatchControlDevicesService'); return false; } } } final class DebouncedBatchControlDevicesService implements BatchControlDevicesService { final BatchControlDevicesService decoratee; final Duration debounceDuration; DebouncedBatchControlDevicesService({ required this.decoratee, this.debounceDuration = const Duration(milliseconds: 1500), }); final _pendingRequests = <(List uuids, String code, Object value)>[]; var _isProcessing = false; @override Future batchControlDevices({ required List uuids, required String code, required Object value, }) async { _pendingRequests.add((uuids, code, value)); if (_isProcessing) return false; _isProcessing = true; await Future.delayed(debounceDuration); final groupedRequests = uuids, String code, Object value)>{}; for (final request in _pendingRequests) { final (_, requestCode, requestValue) = request; groupedRequests[requestCode] = request; } _pendingRequests.clear(); try { var allSuccessful = true; for (final request in groupedRequests.values) { final (lastRequestUuids, lastRequestCode, lastRequestValue) = request; final success = await decoratee.batchControlDevices( uuids: lastRequestUuids, code: lastRequestCode, value: lastRequestValue, ); if (!success) allSuccessful = false; } return allSuccessful; } finally { _isProcessing = false; } } }