import 'package:flutter/material.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/customer/customer.dart'; import '../../../components/spacer/spacer.dart'; class CustomerCard extends StatelessWidget { final Customer customer; final VoidCallback? onTap; final VoidCallback? onLongPress; const CustomerCard({ super.key, required this.customer, this.onTap, this.onLongPress, }); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( color: AppColor.white, borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.06), blurRadius: 20, offset: const Offset(0, 6), spreadRadius: -4, ), ], border: Border.all( color: customer.isActive ? AppColor.primary.withOpacity(0.1) : Colors.grey.withOpacity(0.08), width: 1.5, ), ), child: Material( color: Colors.transparent, child: InkWell( onTap: onTap, onLongPress: onLongPress, borderRadius: BorderRadius.circular(20), child: Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Avatar with status indicator Stack( children: [ Container( decoration: BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ _getAvatarColor(customer.name), _getAvatarColor(customer.name).withOpacity(0.8), ], ), boxShadow: [ BoxShadow( color: _getAvatarColor( customer.name, ).withOpacity(0.3), blurRadius: 12, offset: const Offset(0, 4), ), ], ), child: CircleAvatar( backgroundColor: Colors.transparent, radius: 32, child: Text( customer.name.isNotEmpty ? customer.name[0].toUpperCase() : '?', style: AppStyle.xxl.copyWith( color: AppColor.white, fontWeight: FontWeight.bold, ), ), ), ), // Status indicator Positioned( bottom: 2, right: 2, child: Container( width: 20, height: 20, decoration: BoxDecoration( color: customer.isActive ? AppColor.success : AppColor.error, shape: BoxShape.circle, border: Border.all(color: AppColor.white, width: 3), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 4, offset: const Offset(0, 2), ), ], ), ), ), // Default badge if (customer.isDefault) Positioned( top: -2, left: -8, child: Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2, ), decoration: BoxDecoration( color: AppColor.primary, borderRadius: BorderRadius.circular(8), boxShadow: [ BoxShadow( color: AppColor.primary.withOpacity(0.3), blurRadius: 4, offset: const Offset(0, 2), ), ], ), child: Text( '⭐', style: AppStyle.xs.copyWith( color: AppColor.white, fontWeight: FontWeight.bold, ), ), ), ), ], ), const SpaceHeight(16), // Customer Name Text( customer.name.isNotEmpty ? customer.name : 'Unknown Customer', style: AppStyle.lg.copyWith( fontWeight: FontWeight.bold, color: AppColor.textPrimary, ), textAlign: TextAlign.center, maxLines: 2, overflow: TextOverflow.ellipsis, ), const SpaceHeight(8), // Contact Info if (customer.email.isNotEmpty || customer.phone.isNotEmpty) ...[ Column( children: [ if (customer.email.isNotEmpty) _buildContactInfo(Icons.email_outlined, customer.email), if (customer.email.isNotEmpty && customer.phone.isNotEmpty) const SpaceHeight(4), if (customer.phone.isNotEmpty) _buildContactInfo(Icons.phone_outlined, customer.phone), ], ), const SpaceHeight(12), ], // Status Badge Container( padding: const EdgeInsets.symmetric( horizontal: 12, vertical: 6, ), decoration: BoxDecoration( color: customer.isActive ? AppColor.success.withOpacity(0.1) : AppColor.error.withOpacity(0.1), borderRadius: BorderRadius.circular(16), border: Border.all( color: customer.isActive ? AppColor.success.withOpacity(0.3) : AppColor.error.withOpacity(0.3), width: 1, ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Container( width: 8, height: 8, decoration: BoxDecoration( color: customer.isActive ? AppColor.success : AppColor.error, shape: BoxShape.circle, ), ), const SpaceWidth(6), Text( customer.isActive ? 'Active' : 'Inactive', style: AppStyle.sm.copyWith( color: customer.isActive ? AppColor.success : AppColor.error, fontWeight: FontWeight.w600, ), ), ], ), ), // Additional info if available if (customer.address.isNotEmpty) ...[ const SpaceHeight(8), Row( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.location_on_outlined, size: 14, color: AppColor.textSecondary, ), const SpaceWidth(4), Flexible( child: Text( customer.address, style: AppStyle.xs.copyWith( color: AppColor.textSecondary, ), textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), ], // Metadata info if (customer.metadata.isNotEmpty && _hasRelevantMetadata()) ...[ const SpaceHeight(8), Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: AppColor.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.star_outline, size: 12, color: AppColor.primary, ), const SpaceWidth(4), Text( _getMetadataInfo(), style: AppStyle.xs.copyWith( color: AppColor.primary, fontWeight: FontWeight.w500, ), ), ], ), ), ], // Join date if (customer.createdAt.isNotEmpty) ...[ const SpaceHeight(8), Text( 'Joined ${_formatDate(customer.createdAt)}', style: AppStyle.xs.copyWith(color: AppColor.textSecondary), textAlign: TextAlign.center, ), ], ], ), ), ), ), ); } Widget _buildContactInfo(IconData icon, String text) { return Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 14, color: AppColor.textSecondary), const SpaceWidth(6), Flexible( child: Text( text, style: AppStyle.sm.copyWith(color: AppColor.textSecondary), textAlign: TextAlign.center, maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ); } Color _getAvatarColor(String name) { final colors = [ AppColor.primary, const Color(0xFF9C27B0), // Purple const Color(0xFFFF9800), // Orange const Color(0xFF607D8B), // Blue Grey const Color(0xFF795548), // Brown const Color(0xFF4CAF50), // Green const Color(0xFF2196F3), // Blue const Color(0xFFE91E63), // Pink const Color(0xFF00BCD4), // Cyan const Color(0xFFFF5722), // Deep Orange ]; if (name.isEmpty) return AppColor.primary; final index = name.hashCode.abs() % colors.length; return colors[index]; } String _formatDate(String dateStr) { try { final date = DateTime.parse(dateStr); final now = DateTime.now(); final difference = now.difference(date).inDays; if (difference == 0) { return 'today'; } else if (difference == 1) { return 'yesterday'; } else if (difference < 30) { return '${difference}d ago'; } else if (difference < 365) { final months = (difference / 30).floor(); return '${months}mo ago'; } else { final years = (difference / 365).floor(); return '${years}y ago'; } } catch (e) { return dateStr; } } bool _hasRelevantMetadata() { return customer.metadata.containsKey('notes') || customer.metadata.containsKey('tags') || customer.metadata.containsKey('source') || customer.metadata.containsKey('preferences') || customer.metadata.containsKey('vip') || customer.metadata.containsKey('tier'); } String _getMetadataInfo() { if (customer.metadata.containsKey('vip') && customer.metadata['vip'] == true) { return 'VIP'; } if (customer.metadata.containsKey('tier')) { return customer.metadata['tier'].toString(); } if (customer.metadata.containsKey('tags')) { final tags = customer.metadata['tags']; if (tags is List && tags.isNotEmpty) { return tags.first.toString(); } } if (customer.metadata.containsKey('source')) { return customer.metadata['source'].toString(); } return 'Special'; } }