import 'dart:ui'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/community_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/connection_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/subspace_model.dart'; import 'package:syncrow_web/pages/spaces_management/all_spaces/model/tag.dart'; import 'package:syncrow_web/pages/spaces_management/space_model/models/space_template_model.dart'; import 'package:syncrow_web/utils/constants/assets.dart'; import 'package:uuid/uuid.dart'; enum SpaceStatus { newSpace, modified, unchanged, deleted } class SpaceModel { String? uuid; String? icon; final String? spaceTuyaUuid; String name; final bool isPrivate; final String? invitationCode; SpaceModel? parent; final CommunityModel? community; List children; Offset position; bool isHovered; SpaceStatus status; String internalId; SpaceTemplateModel? spaceModel; List? tags; List? subspaces; List outgoingConnections = []; // Connections from this space Connection? incomingConnection; // Connections to this space SpaceModel({ this.uuid, String? internalId, this.spaceTuyaUuid, required this.icon, required this.name, required this.isPrivate, this.invitationCode, this.parent, this.community, required this.children, required this.position, this.isHovered = false, this.incomingConnection, this.status = SpaceStatus.unchanged, this.spaceModel, this.tags, this.subspaces, }) : internalId = internalId ?? const Uuid().v4(); factory SpaceModel.fromJson(Map json, {String? parentInternalId}) { final String internalId = json['internalId'] ?? const Uuid().v4(); final List children = json['children'] != null ? (json['children'] as List).map((childJson) { return SpaceModel.fromJson( childJson, parentInternalId: internalId, ); }).toList() : []; final instance = SpaceModel( internalId: internalId, uuid: json['uuid'] ?? '', spaceTuyaUuid: json['spaceTuyaUuid'], name: json['spaceName'], isPrivate: json['isPrivate'] ?? false, invitationCode: json['invitationCode'], subspaces: (json['subspaces'] as List?) ?.where((e) => e is Map) // Validate type .map((e) => SubspaceModel.fromJson(e as Map)) .toList() ?? [], parent: parentInternalId != null ? SpaceModel( internalId: parentInternalId, uuid: json['parent']?['uuid'], spaceTuyaUuid: json['parent']?['spaceTuyaUuid'], name: json['parent']?['spaceName'] ?? '', isPrivate: json['parent']?['isPrivate'] ?? false, invitationCode: json['parent']?['invitationCode'], children: [], position: Offset(json['parent']?['x'] ?? 0, json['parent']?['y'] ?? 0), icon: json['parent']?['icon'] ?? Assets.location, ) : null, community: json['community'] != null ? CommunityModel.fromJson(json['community']) : null, children: children, icon: json['icon'] ?? Assets.location, position: Offset(json['x'] ?? 0, json['y'] ?? 0), isHovered: false, tags: (json['tags'] as List?) ?.where((item) => item is Map) // Validate type .map((item) => Tag.fromJson(item as Map)) .toList() ?? [], ); if (json['incomingConnections'] != null && json['incomingConnections'] is List && (json['incomingConnections'] as List).isNotEmpty && instance.parent != null) { final conn = json['incomingConnections'][0]; instance.incomingConnection = Connection( startSpace: instance.parent ?? instance, // Parent space endSpace: instance, // This space instance direction: conn['direction'], ); } return instance; } Map toMap() { return { 'uuid': uuid ?? '', 'spaceTuyaUuid': spaceTuyaUuid, 'name': name, 'isPrivate': isPrivate, 'invitationCode': invitationCode, 'parent': parent?.uuid, 'subspaces': subspaces?.map((e) => e.toJson()).toList(), 'community': community?.toMap(), 'children': children.map((child) => child.toMap()).toList(), 'icon': icon, 'position': {'dx': position.dx, 'dy': position.dy}, 'isHovered': isHovered, 'outgoingConnections': outgoingConnections.map((c) => c.toMap()).toList(), 'incomingConnection': incomingConnection?.toMap(), 'tags': tags?.map((e) => e.toJson()).toList(), }; } void addOutgoingConnection(Connection connection) { outgoingConnections.add(connection); } } extension SpaceExtensions on SpaceModel { List listAllTagValues() { final List tagValues = []; if (tags != null) { tagValues.addAll( tags!.map((tag) => tag.tag ?? '').where((tag) => tag.isNotEmpty)); } if (subspaces != null) { for (final subspace in subspaces!) { if (subspace.tags != null) { tagValues.addAll( subspace.tags! .map((tag) => tag.tag ?? '') .where((tag) => tag.isNotEmpty), ); } } } return tagValues; } }