import '../models/automation_rule.dart'; import '../models/device.dart'; import '../models/device_type.dart'; import '../models/zone.dart'; import 'api_client.dart'; /// Typed wrappers for every `/api/v1` endpoint besides auth (see /// [AuthService] for login/logout/me). One method per backend action — /// no generic "request" escape hatch, so call sites stay self-documenting. class ApiService { ApiService(this._client); final ApiClient _client; // --- Zones --- Future> zones() async { final json = await _client.get('/zones'); return _list(json).map(Zone.fromJson).toList(); } Future createZone({required String name, String? description}) async { final json = await _client.post('/zones', { 'name': name, if (description != null && description.isNotEmpty) 'description': description, }); return Zone.fromJson(json['data'] as Map); } Future updateZone(int id, {required String name, String? description}) async { final json = await _client.put('/zones/$id', { 'name': name, if (description != null && description.isNotEmpty) 'description': description, }); return Zone.fromJson(json['data'] as Map); } Future deleteZone(int id) => _client.delete('/zones/$id'); // --- Device types --- Future> deviceTypes() async { final json = await _client.get('/device-types'); return _list(json).map(DeviceType.fromJson).toList(); } // --- Devices --- Future> devices() async { final json = await _client.get('/devices'); return _list(json).map(Device.fromJson).toList(); } Future device(int id) async { final json = await _client.get('/devices/$id'); return DeviceDetail.fromJson(json as Map); } Future createDevice({ required int zoneId, required int deviceTypeId, required String name, required String externalId, String protocol = 'mqtt', }) async { final json = await _client.post('/devices', { 'zone_id': zoneId, 'device_type_id': deviceTypeId, 'name': name, 'external_id': externalId, 'protocol': protocol, }); return Device.fromJson(json['data'] as Map); } Future updateDevice( int id, { required int zoneId, required int deviceTypeId, required String name, required String externalId, String protocol = 'mqtt', }) async { final json = await _client.put('/devices/$id', { 'zone_id': zoneId, 'device_type_id': deviceTypeId, 'name': name, 'external_id': externalId, 'protocol': protocol, }); return Device.fromJson(json['data'] as Map); } Future deleteDevice(int id) => _client.delete('/devices/$id'); Future turnOn(int deviceId) => _commandMessage(_client.post('/devices/$deviceId/turn-on')); Future turnOff(int deviceId) => _commandMessage(_client.post('/devices/$deviceId/turn-off')); Future setLevel(int deviceId, double level) => _commandMessage(_client.post('/devices/$deviceId/set-level', {'level': level})); Future _commandMessage(Future request) async { final json = await request; return (json as Map)['message'] as String? ?? 'Готово.'; } // --- Automation rules --- Future> automationRules() async { final json = await _client.get('/automation-rules'); return _list(json).map(AutomationRule.fromJson).toList(); } Future createAutomationRule(Map payload) async { final json = await _client.post('/automation-rules', payload); return AutomationRule.fromJson(json['data'] as Map); } Future updateAutomationRule(int id, Map payload) async { final json = await _client.put('/automation-rules/$id', payload); return AutomationRule.fromJson(json['data'] as Map); } Future deleteAutomationRule(int id) => _client.delete('/automation-rules/$id'); List> _list(dynamic json) => List>.from((json as Map)['data'] as List); }