import 'package:syncrow_app/features/devices/model/function_model.dart'; import 'package:syncrow_app/features/devices/model/status_model.dart'; import 'package:syncrow_app/generated/assets.dart'; import 'package:syncrow_app/utils/resource_manager/constants.dart'; class DeviceModel { int? activeTime; // String? id; String? localKey; String? model; String? name; String? icon; String? categoryName; bool? toggleStatus = false; String? type; bool? isOnline; List status = []; String? productName; String? timeZone; int? updateTime; String? uuid; String? productUuid; DeviceType? productType; bool isSelected = false; late List functions; DeviceSubspace? subspace; DeviceModel( {this.activeTime, this.productUuid, this.localKey, this.model, this.name, this.isOnline, required this.status, this.productName, this.timeZone, this.updateTime, this.uuid, this.productType, this.categoryName, this.subspace, this.toggleStatus, this.icon, this.type}) { functions = getFunctions(productType!); } factory DeviceModel.fromJson(Map json) { String tempIcon = ''; DeviceType type = devicesTypesMap[json['productType']] ?? DeviceType.Other; if (type == DeviceType.LightBulb) { tempIcon = Assets.assetsIconsLight; } else if (type == DeviceType.CeilingSensor || type == DeviceType.WallSensor) { tempIcon = Assets.assetsIconsSensors; } else if (type == DeviceType.AC) { tempIcon = Assets.assetsIconsAC; } else if (type == DeviceType.DoorLock) { tempIcon = Assets.assetsIconsDoorLock; } else if (type == DeviceType.Curtain) { tempIcon = Assets.assetsIconsCurtain; } else if (type == DeviceType.ThreeGang) { tempIcon = Assets.assetsIcons3GangSwitch; } else if (type == DeviceType.Gateway) { tempIcon = Assets.assetsIconsGateway; } else if (type == DeviceType.OneGang) { tempIcon = Assets.oneGang; } else if (type == DeviceType.TwoGang) { tempIcon = Assets.twoGang; } else if (type == DeviceType.WH) { tempIcon = Assets.waterHeaterIcon; } else if (type == DeviceType.DS) { tempIcon = Assets.doorSensorIcon; } else if (type == DeviceType.OneTouch) { tempIcon = Assets.gang1touch; } else if (type == DeviceType.TowTouch) { tempIcon = Assets.gang2touch; } else if (type == DeviceType.GarageDoor) { tempIcon = Assets.garageIcon; } else if (type == DeviceType.ThreeTouch) { tempIcon = Assets.gang3touch; } else if (type == DeviceType.WaterLeak) { tempIcon = Assets.waterLeakIcon; } else if (type == DeviceType.PC) { tempIcon = Assets.powerClampIcon; } else if (type == DeviceType.FourScene) { tempIcon = Assets.fourSceneHomeIcon; } else if (type == DeviceType.SixScene) { tempIcon = Assets.sixSceneHomeIcon; } else if (type == DeviceType.SOS) { tempIcon = Assets.sosHomeIcon; } else if (type == DeviceType.FlushMountedSensor) { tempIcon = Assets.flushIcon; } else { tempIcon = Assets.assetsIconsLogo; } // Step 1: Parse `status` as before final statusList = (json['status'] as List?) ?.map((st) => StatusModel.fromJson(st as Map)) .toList(); // Step 2: Check whether ANY status means "off" final anyOff = statusList?.any((s) { final code = s.code; if (code == null) return false; // 1) Handle "switch" or "switch_x" if (code == 'switch' || code.startsWith('switch_')) { // If it's false, we consider that "off" return s.value == false; } // 2) If code == "control" and value == "stop", consider "off" if (s.value == 'open') { return true; } // 3) If code == "percent_control" and value == 0, maybe "off" if (code == 'percent_control' && s.value == 0) { return true; } // Add more conditions for other codes as needed // Default: if none of the above apply, it's not "off" return false; }); // Step 3: Decide final toggleStatus (true = fully "on", false = partially/fully "off") bool computedToggleStatus = !(anyOff ?? false); return DeviceModel( icon: tempIcon, activeTime: json['activeTime'], categoryName: json['categoryName'], localKey: json['localKey'], model: json['model'], name: json['name'], isOnline: json['online'], productName: json['productName'], timeZone: json['timeZone'], updateTime: json['updateTime'], uuid: json['uuid'], productType: type, type: json['productType'], // Use the newly computed toggleStatus: toggleStatus: computedToggleStatus, // Or if you prefer to use the value returned by the backend when available: // toggleStatus: json['toggleStatus'] ?? computedToggleStatus, status: statusList ?? [], subspace: json['subspace'] != null ? DeviceSubspace.fromJson(json['subspace']) : DeviceSubspace( createdAt: null, disabled: false, subspaceName: '', updatedAt: null, uuid: '', ), productUuid: json['productUuid'], ); } Map toJson() { return { 'activeTime': activeTime, 'localKey': localKey, 'model': model, 'name': name, 'online': isOnline, 'productName': productName, 'timeZone': timeZone, 'updateTime': updateTime, 'uuid': uuid, 'productType': productType, 'subspace': subspace?.toJson(), // serialize subspace }; } List getFunctions(DeviceType type) => devicesFunctionsMap[productType] ?? []; } class DeviceSubspace { String? uuid; DateTime? createdAt; DateTime? updatedAt; String? subspaceName; bool? disabled; DeviceSubspace({ this.uuid, this.createdAt, this.updatedAt, this.subspaceName, this.disabled, }); factory DeviceSubspace.fromJson(Map json) { return DeviceSubspace( uuid: json['uuid'], createdAt: json['createdAt'] != null ? DateTime.tryParse(json['createdAt']) : null, updatedAt: json['updatedAt'] != null ? DateTime.tryParse(json['updatedAt']) : null, subspaceName: json['subspaceName'], disabled: json['disabled'], ); } Map toJson() { return { 'uuid': uuid, 'createdAt': createdAt?.toIso8601String(), 'updatedAt': updatedAt?.toIso8601String(), 'subspaceName': subspaceName, 'disabled': disabled, }; } }