import 'package:p_tits_pas/models/user.dart'; import 'package:p_tits_pas/utils/enfant_status_utils.dart'; /// Enfant tel que renvoyé par `GET /enfants` (dashboard admin). class EnfantAdminModel { final String id; final String? firstName; final String? lastName; final String? gender; final String? birthDate; final String? dueDate; final String status; final String? photoUrl; final bool consentPhoto; final bool isMultiple; final List parentLinks; EnfantAdminModel({ required this.id, this.firstName, this.lastName, this.gender, this.birthDate, this.dueDate, required this.status, this.photoUrl, this.consentPhoto = false, this.isMultiple = false, this.parentLinks = const [], }); String get fullName { final fn = (firstName ?? '').trim(); final ln = (lastName ?? '').trim(); if (fn.isEmpty && ln.isEmpty) return 'Enfant'; if (ln.isEmpty) return fn; return '$fn $ln'; } /// Aucun lien parent valide (`enfants_parents` vide) — ticket #157. bool get hasNoResponsable => !parentLinks.any((l) => l.parentId.trim().isNotEmpty); EnfantAdminModel copyWith({ String? id, String? firstName, String? lastName, String? gender, String? birthDate, String? dueDate, String? status, String? photoUrl, bool? consentPhoto, bool? isMultiple, List? parentLinks, }) { return EnfantAdminModel( id: id ?? this.id, firstName: firstName ?? this.firstName, lastName: lastName ?? this.lastName, gender: gender ?? this.gender, birthDate: birthDate ?? this.birthDate, dueDate: dueDate ?? this.dueDate, status: status ?? this.status, photoUrl: photoUrl ?? this.photoUrl, consentPhoto: consentPhoto ?? this.consentPhoto, isMultiple: isMultiple ?? this.isMultiple, parentLinks: parentLinks ?? this.parentLinks, ); } factory EnfantAdminModel.fromJson(Map json) { final linksRaw = json['parentLinks'] as List?; final links = []; if (linksRaw != null) { for (final item in linksRaw) { if (item is Map) { links.add(EnfantParentLink.fromJson(item)); } } } final photoUrl = json['photo_url'] as String? ?? json['photoUrl'] as String?; final consentPhoto = _parseBool(json['consent_photo']) || _parseBool(json['consentement_photo']) || _parseBool(json['consentPhoto']); return EnfantAdminModel( id: (json['id'] ?? '').toString(), firstName: json['first_name'] as String? ?? json['prenom'] as String?, lastName: json['last_name'] as String? ?? json['nom'] as String?, gender: json['gender'] as String? ?? json['genre'] as String?, birthDate: _dateString(json['birth_date'] ?? json['date_naissance']), dueDate: _dateString(json['due_date'] ?? json['date_prevue_naissance']), status: normalizeEnfantStatus( (json['status'] ?? json['statut'])?.toString(), ), photoUrl: photoUrl, consentPhoto: consentPhoto, isMultiple: _parseBool(json['is_multiple']) || _parseBool(json['est_multiple']), parentLinks: links, ); } Map toUpdateJson() { return { if (firstName != null) 'first_name': firstName, if (lastName != null) 'last_name': lastName, if (gender != null && gender!.isNotEmpty) 'gender': gender, 'status': status, if (birthDate != null && birthDate!.isNotEmpty) 'birth_date': birthDate, if (dueDate != null && dueDate!.isNotEmpty) 'due_date': dueDate, 'consent_photo': consentPhoto, 'is_multiple': isMultiple, }; } static bool _parseBool(dynamic value) { if (value == true || value == 1) return true; if (value is String) { final s = value.trim().toLowerCase(); return s == 'true' || s == '1' || s == 't' || s == 'yes'; } return false; } static String? _dateString(dynamic v) { if (v == null) return null; if (v is String) return v.split('T').first; return v.toString().split('T').first; } } class EnfantParentLink { final String parentId; final String? parentName; EnfantParentLink({required this.parentId, this.parentName}); EnfantParentLink copyWith({String? parentId, String? parentName}) { return EnfantParentLink( parentId: parentId ?? this.parentId, parentName: parentName ?? this.parentName, ); } factory EnfantParentLink.fromJson(Map json) { final parentId = (json['parentId'] ?? json['id_parent'] ?? '').toString(); String? name; final parent = json['parent']; if (parent is Map) { final user = parent['user']; if (user is Map) { final u = AppUser.fromJson(user); name = u.fullName.isNotEmpty ? u.fullName : u.email; } else { // Parfois le parent est aplati (prenom/nom) sans nested user. final prenom = (parent['prenom'] ?? parent['first_name'] ?? '').toString().trim(); final nom = (parent['nom'] ?? parent['last_name'] ?? '').toString().trim(); final flat = '$prenom $nom'.trim(); if (flat.isNotEmpty) name = flat; } } return EnfantParentLink( parentId: parentId, parentName: name, ); } }