import 'package:flutter/material.dart'; import '../../../../common/extension/extension.dart'; import '../../../../common/theme/theme.dart'; import '../../../../domain/customer/customer.dart'; import '../../../components/spacer/spacer.dart'; class CustomerTile extends StatelessWidget { final Customer customer; final VoidCallback? onTap; final VoidCallback? onEdit; final VoidCallback? onDelete; const CustomerTile({ super.key, required this.customer, this.onTap, this.onEdit, this.onDelete, }); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), decoration: BoxDecoration( color: AppColor.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.06), blurRadius: 16, offset: const Offset(0, 4), spreadRadius: -2, ), ], border: Border.all( color: customer.isActive ? AppColor.primary.withOpacity(0.15) : Colors.grey.withOpacity(0.1), width: 1, ), ), child: Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(16), onTap: onTap, child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Row Row( children: [ // Avatar Stack( children: [ CircleAvatar( radius: 26, backgroundColor: _getAvatarColor(customer.name), child: Text( customer.name.isNotEmpty ? customer.name[0].toUpperCase() : '?', style: AppStyle.lg.copyWith( color: AppColor.white, fontWeight: FontWeight.bold, ), ), ), // Status indicator Positioned( bottom: 2, right: 2, child: Container( width: 16, height: 16, decoration: BoxDecoration( color: customer.isActive ? AppColor.success : AppColor.error, shape: BoxShape.circle, border: Border.all( color: AppColor.white, width: 2, ), ), ), ), ], ), const SpaceWidth(16), // Customer Info Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Name with badges Row( children: [ Expanded( child: Text( customer.name.isNotEmpty ? customer.name : 'Unknown Customer', style: AppStyle.lg.copyWith( fontWeight: FontWeight.bold, color: AppColor.textPrimary, ), overflow: TextOverflow.ellipsis, ), ), if (customer.isDefault) Container( padding: const EdgeInsets.symmetric( horizontal: 8, vertical: 4, ), decoration: BoxDecoration( color: AppColor.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Text( 'DEFAULT', style: AppStyle.xs.copyWith( color: AppColor.primary, fontWeight: FontWeight.bold, letterSpacing: 0.5, ), ), ), ], ), const SpaceHeight(4), // Contact info if (customer.email.isNotEmpty) ...[ Row( children: [ Icon( Icons.email_outlined, size: 16, color: AppColor.textSecondary, ), const SpaceWidth(6), Expanded( child: Text( customer.email, style: AppStyle.sm.copyWith( color: AppColor.textSecondary, ), overflow: TextOverflow.ellipsis, ), ), ], ), const SpaceHeight(4), ], if (customer.phone.isNotEmpty) Row( children: [ Icon( Icons.phone_outlined, size: 16, color: AppColor.textSecondary, ), const SpaceWidth(6), Text( customer.phone, style: AppStyle.sm.copyWith( color: AppColor.textSecondary, ), ), ], ), ], ), ), ], ), // Address section if (customer.address.isNotEmpty) ...[ const SpaceHeight(16), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColor.background, borderRadius: BorderRadius.circular(12), ), child: Row( children: [ Icon( Icons.location_on_outlined, size: 18, color: AppColor.textSecondary, ), const SpaceWidth(8), Expanded( child: Text( customer.address, style: AppStyle.sm.copyWith( color: AppColor.textSecondary, ), maxLines: 2, overflow: TextOverflow.ellipsis, ), ), ], ), ), ], // Footer with status and dates const SpaceHeight(16), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ // 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(20), ), 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 ? context.lang.active : context.lang.inactive, style: AppStyle.sm.copyWith( color: customer.isActive ? AppColor.success : AppColor.error, fontWeight: FontWeight.w600, ), ), ], ), ), // Created date if (customer.createdAt.isNotEmpty) Text( '${context.lang.joined} ${_formatDate(context, customer.createdAt)}', style: AppStyle.xs.copyWith( color: AppColor.textSecondary, ), ), ], ), // Metadata section (if has any relevant data) if (customer.metadata.isNotEmpty && _hasRelevantMetadata()) ...[ const SpaceHeight(12), Container( width: double.infinity, padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: AppColor.primary.withOpacity(0.05), borderRadius: BorderRadius.circular(12), border: Border.all( color: AppColor.primary.withOpacity(0.1), width: 1, ), ), child: Row( children: [ Icon( Icons.info_outline, size: 16, color: AppColor.primary, ), const SpaceWidth(8), Expanded( child: Text( _getMetadataInfo(), style: AppStyle.xs.copyWith( color: AppColor.primary, ), ), ), ], ), ), ], ], ), ), ), ), ); } Color _getAvatarColor(String name) { final colors = [ AppColor.primary, const Color(0xFF9C27B0), const Color(0xFFFF9800), const Color(0xFF607D8B), const Color(0xFF795548), const Color(0xFF4CAF50), const Color(0xFF2196F3), const Color(0xFFE91E63), ]; final index = name.hashCode.abs() % colors.length; return colors[index]; } String _formatDate(BuildContext context, 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 ${context.lang.ago}'; } else if (difference < 365) { final months = (difference / 30).floor(); return '${months}mo ${context.lang.ago}'; } else { final years = (difference / 365).floor(); return '${years}y ${context.lang.ago}'; } } catch (e) { return dateStr; } } bool _hasRelevantMetadata() { return customer.metadata.containsKey('notes') || customer.metadata.containsKey('tags') || customer.metadata.containsKey('source') || customer.metadata.containsKey('preferences'); } String _getMetadataInfo() { final info = []; if (customer.metadata.containsKey('notes')) { info.add('Has notes'); } if (customer.metadata.containsKey('tags')) { final tags = customer.metadata['tags']; if (tags is List && tags.isNotEmpty) { info.add('${tags.length} tags'); } } if (customer.metadata.containsKey('source')) { info.add('Source: ${customer.metadata['source']}'); } return info.join(' • '); } }