import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import '../../../core/constants/design_system.dart'; import '../../../core/utils/page_transitions.dart'; import '../../../data/datasources/chat_remote_data_source.dart'; import '../../../data/services/secure_storage.dart'; import '../../../domain/entities/friend.dart'; import '../../screens/chat/chat_screen.dart'; import '../animated_widgets.dart'; import '../custom_snackbar.dart'; import '../friend_detail_screen.dart'; import '../social_badge_widget.dart'; /// [FriendCard] est un widget qui représente la carte d'un ami dans la liste. /// Il affiche une image de profil, le nom, le statut, la dernière interaction, /// un voyant pour l'état en ligne, et la durée de l'amitié. class FriendCard extends StatefulWidget { const FriendCard({required this.friend, super.key}); final Friend friend; @override State createState() => _FriendCardState(); } class _FriendCardState extends State { final ChatRemoteDataSource _chatDataSource = ChatRemoteDataSource(http.Client()); final SecureStorage _storage = SecureStorage(); bool _isCreatingConversation = false; @override Widget build(BuildContext context) { // Calcul de la durée de l'amitié final duration = _calculateFriendshipDuration(widget.friend.dateAdded); return AnimatedCard( onTap: () => _navigateToFriendDetail(context), elevation: DesignSystem.elevationSm, hoverElevation: DesignSystem.elevationLg, borderRadius: DesignSystem.borderRadiusLg, padding: DesignSystem.paddingAll(DesignSystem.spacingMd), child: Column( children: [ Stack( alignment: Alignment.topRight, children: [ Hero( tag: 'friend_avatar_${widget.friend.friendId}', child: CircleAvatar( radius: 50, backgroundImage: _getImageProvider(), ), ), // Indicateur de statut en ligne Positioned( right: 0, top: 0, child: AnimatedSwitcher( duration: const Duration(milliseconds: 200), child: CircleAvatar( key: ValueKey(widget.friend.isOnline ?? false), radius: 8, backgroundColor: (widget.friend.isOnline ?? false) ? Colors.green : Colors.grey, ), ), ), ], ), const SizedBox(height: 10), Text( '${widget.friend.friendFirstName} ${widget.friend.friendLastName}', style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 16, ), ), const SizedBox(height: 5), Text( widget.friend.status.name, style: const TextStyle(fontSize: 14), ), const SizedBox(height: 5), Text( widget.friend.lastInteraction ?? 'Aucune interaction récente', style: const TextStyle( fontStyle: FontStyle.italic, fontSize: 12, ), ), const SizedBox(height: 10), // Affichage de la durée de l'amitié Text( 'Amis depuis: $duration', style: const TextStyle( fontSize: 12, color: Colors.grey, ), ), const SizedBox(height: 10), // Affichage des badges Row( mainAxisAlignment: MainAxisAlignment.center, children: _buildBadges(), ), const SizedBox(height: 8), // Bouton de message compact SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: _isCreatingConversation ? null : _openChat, icon: _isCreatingConversation ? const SizedBox( width: 14, height: 14, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.chat_bubble_outline_rounded, size: 16), label: Text( _isCreatingConversation ? 'Envoi...' : 'Message', style: const TextStyle(fontSize: 13, fontWeight: FontWeight.w500), ), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 1, minimumSize: Size.zero, tapTargetSize: MaterialTapTargetSize.shrinkWrap, ), ), ), ], ), ); } Future _openChat() async { final userId = await _storage.getUserId(); if (userId == null) { if (mounted) { context.showError('Erreur: Utilisateur non connecté'); } return; } setState(() { _isCreatingConversation = true; }); try { // Obtenir ou créer la conversation final conversationModel = await _chatDataSource.getOrCreateConversation( userId, widget.friend.friendId, ); if (mounted) { setState(() { _isCreatingConversation = false; }); // Naviguer vers l'écran de chat context.pushSlideUp(ChatScreen(conversation: conversationModel.toEntity())); } } catch (e) { if (mounted) { setState(() { _isCreatingConversation = false; }); context.showError('Erreur lors de l\'ouverture du chat'); } } } /// Retourne l'image de l'ami, soit à partir d'une URL soit une image par défaut. ImageProvider _getImageProvider() { return widget.friend.imageUrl != null && widget.friend.imageUrl!.isNotEmpty ? (widget.friend.imageUrl!.startsWith('https') ? NetworkImage(widget.friend.imageUrl!) // Image depuis une URL : AssetImage(widget.friend.imageUrl!) as ImageProvider) // Image locale : const AssetImage('lib/assets/images/default_avatar.png'); // Image par défaut } /// Calcule la durée de l'amitié depuis la date d'ajout. String _calculateFriendshipDuration(String? dateAdded) { if (dateAdded == null || dateAdded.isEmpty) return 'Inconnu'; final date = DateTime.parse(dateAdded); final duration = DateTime.now().difference(date); if (duration.inDays < 30) { return '${duration.inDays} jour${duration.inDays > 1 ? 's' : ''}'; } else if (duration.inDays < 365) { final months = (duration.inDays / 30).floor(); return '$months mois'; } else { final years = (duration.inDays / 365).floor(); return '$years an${years > 1 ? 's' : ''}'; } } /// Navigation vers l'écran de détails de l'ami void _navigateToFriendDetail(BuildContext context) { debugPrint( "[LOG] Navigation : Détails de l'ami ${widget.friend.friendFirstName} ${widget.friend.friendLastName}",); context.pushFadeScale( FriendDetailScreen( friendFirstName: widget.friend.friendFirstName, friendLastName: widget.friend.friendLastName, imageUrl: widget.friend.imageUrl ?? '', friendId: widget.friend.friendId, status: widget.friend.status, lastInteraction: widget.friend.lastInteraction ?? 'Aucune', dateAdded: widget.friend.dateAdded ?? 'Inconnu', ), ); } /// Crée une liste de badges à afficher sur la carte de l'ami. List _buildBadges() { final List badges = []; // Exemple de badges en fonction des attributs de l'ami if (widget.friend.isBestFriend != null && widget.friend.isBestFriend == true) { badges.add(const BadgeWidget( badge: 'Meilleur Ami', icon: Icons.star, ),); } if (widget.friend.hasKnownSinceChildhood != null && widget.friend.hasKnownSinceChildhood == true) { badges.add(const BadgeWidget( badge: 'Ami d\'enfance', icon: Icons.child_care, ),); } if (widget.friend.isOnline != null && widget.friend.isOnline == true) { badges.add(const BadgeWidget( badge: 'En ligne', icon: Icons.circle, ),); } // Ajouter d'autres badges si nécessaire return badges; } }