import '../../core/constants/env_config.dart'; import '../../domain/entities/user.dart'; /// Modèle de données pour les utilisateurs (Data Transfer Object). /// /// Cette classe est responsable de la sérialisation/désérialisation /// avec l'API backend et convertit vers/depuis l'entité de domaine [User]. /// /// **Usage:** /// ```dart /// // Depuis JSON /// final user = UserModel.fromJson(jsonData); /// /// // Vers JSON /// final json = user.toJson(); /// /// // Vers entité de domaine /// final entity = user.toEntity(); /// ``` class UserModel extends User { /// Crée une nouvelle instance de [UserModel]. /// /// [userId] L'identifiant unique de l'utilisateur /// [userLastName] Le nom de famille de l'utilisateur /// [userFirstName] Le prénom de l'utilisateur /// [email] L'adresse email de l'utilisateur /// [motDePasse] Le mot de passe (hashé côté serveur) /// [profileImageUrl] L'URL de l'image de profil /// [eventsCount] Le nombre d'événements créés (optionnel) /// [friendsCount] Le nombre d'amis (optionnel) /// [postsCount] Le nombre de posts (optionnel) /// [visitedPlacesCount] Le nombre de lieux visités (optionnel) const UserModel({ required super.userId, required super.userLastName, required super.userFirstName, required super.email, required super.motDePasse, required super.profileImageUrl, super.eventsCount, super.friendsCount, super.postsCount, super.visitedPlacesCount, }); /// Crée un [UserModel] à partir d'un JSON reçu depuis l'API. /// /// [json] Les données JSON à parser /// /// Returns un [UserModel] avec les données parsées /// /// **Note:** Les valeurs par défaut sont utilisées si des champs sont manquants. /// /// **Exemple:** /// ```dart /// final json = { /// 'userId': '123', /// 'nom': 'Doe', /// 'prenoms': 'John', /// 'email': 'john@example.com', /// }; /// final user = UserModel.fromJson(json); /// ``` factory UserModel.fromJson(Map json) { try { // Le backend peut renvoyer 'uuid' ou 'userId', on accepte les deux final userId = _parseString(json, 'userId', '') != '' ? _parseString(json, 'userId', '') : _parseString(json, 'uuid', ''); return UserModel( userId: userId.isNotEmpty ? userId : (json['uuid']?.toString() ?? json['userId']?.toString() ?? ''), userLastName: _parseString(json, 'nom', 'Inconnu'), userFirstName: _parseString(json, 'prenoms', 'Inconnu'), email: _parseString(json, 'email', ''), motDePasse: _parseString(json, 'motDePasse', ''), profileImageUrl: _parseString(json, 'profileImageUrl', ''), eventsCount: _parseInt(json, 'eventsCount') ?? 0, friendsCount: _parseInt(json, 'friendsCount') ?? 0, postsCount: _parseInt(json, 'postsCount') ?? 0, visitedPlacesCount: _parseInt(json, 'visitedPlacesCount') ?? 0, ); } catch (e) { if (EnvConfig.enableDetailedLogs) { print('[UserModel] Erreur lors du parsing JSON: $e'); } rethrow; } } /// Parse une valeur string depuis le JSON avec valeur par défaut. static String _parseString( Map json, String key, String defaultValue, ) { final value = json[key]; if (value == null) return defaultValue; return value.toString(); } /// Parse une valeur int depuis le JSON (optionnel). static int? _parseInt(Map json, String key) { final value = json[key]; if (value == null) return null; if (value is int) return value; if (value is String) { return int.tryParse(value); } return null; } /// Convertit ce [UserModel] en JSON pour l'envoi vers l'API. /// /// Returns une [Map] contenant les données de l'utilisateur /// /// **Note:** Le mot de passe est envoyé en clair (hashé côté serveur). /// /// **Exemple:** /// ```dart /// final user = UserModel(...); /// final json = user.toJson(); /// // Envoyer json à l'API /// ``` @override Map toJson() { final json = { if (userId.isNotEmpty) 'id': userId, 'nom': userLastName, 'prenoms': userFirstName, 'email': email, if (motDePasse.isNotEmpty) 'motDePasse': motDePasse, if (profileImageUrl.isNotEmpty) 'profileImageUrl': profileImageUrl, }; // Ajouter les compteurs optionnels s'ils sont présents if (eventsCount != null) { json['eventsCount'] = eventsCount; } if (friendsCount != null) { json['friendsCount'] = friendsCount; } if (postsCount != null) { json['postsCount'] = postsCount; } if (visitedPlacesCount != null) { json['visitedPlacesCount'] = visitedPlacesCount; } return json; } /// Convertit ce modèle vers une entité de domaine [User]. /// /// Returns une instance de [User] avec les mêmes données /// /// **Exemple:** /// ```dart /// final model = UserModel.fromJson(json); /// final entity = model.toEntity(); /// ``` User toEntity() { return User( userId: userId, userLastName: userLastName, userFirstName: userFirstName, email: email, motDePasse: motDePasse, profileImageUrl: profileImageUrl, eventsCount: eventsCount, friendsCount: friendsCount, postsCount: postsCount, visitedPlacesCount: visitedPlacesCount, ); } /// Crée une copie de ce [UserModel] avec des valeurs modifiées. /// /// Tous les paramètres sont optionnels. Seuls les paramètres fournis /// seront modifiés dans la nouvelle instance. /// /// **Exemple:** /// ```dart /// final updated = user.copyWith( /// userFirstName: 'Jane', /// profileImageUrl: 'https://example.com/new-image.jpg', /// ); /// ``` UserModel copyWith({ String? userId, String? userLastName, String? userFirstName, String? email, String? motDePasse, String? profileImageUrl, int? eventsCount, int? friendsCount, int? postsCount, int? visitedPlacesCount, }) { return UserModel( userId: userId ?? this.userId, userLastName: userLastName ?? this.userLastName, userFirstName: userFirstName ?? this.userFirstName, email: email ?? this.email, motDePasse: motDePasse ?? this.motDePasse, profileImageUrl: profileImageUrl ?? this.profileImageUrl, eventsCount: eventsCount ?? this.eventsCount, friendsCount: friendsCount ?? this.friendsCount, postsCount: postsCount ?? this.postsCount, visitedPlacesCount: visitedPlacesCount ?? this.visitedPlacesCount, ); } @override String toString() { return 'UserModel(' 'userId: $userId, ' 'name: $userFirstName $userLastName, ' 'email: $email' ')'; } }