import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../models/supplement.dart'; import '../providers/supplement_provider.dart'; class SupplementCard extends StatefulWidget { final Supplement supplement; final VoidCallback onTake; final VoidCallback onEdit; final VoidCallback onDelete; final VoidCallback onArchive; const SupplementCard({ super.key, required this.supplement, required this.onTake, required this.onEdit, required this.onDelete, required this.onArchive, }); @override State createState() => _SupplementCardState(); } class _SupplementCardState extends State { bool _isExpanded = false; @override Widget build(BuildContext context) { return Consumer( builder: (context, provider, child) { final bool isTakenToday = provider.hasBeenTakenToday(widget.supplement.id!); final int todayIntakeCount = provider.getTodayIntakeCount(widget.supplement.id!); final bool isCompletelyTaken = todayIntakeCount >= widget.supplement.frequencyPerDay; // Get today's intake times for this supplement final todayIntakes = provider.todayIntakes .where((intake) => intake['supplement_id'] == widget.supplement.id) .map((intake) { final takenAt = DateTime.parse(intake['takenAt']); final unitsTaken = intake['unitsTaken'] ?? 1.0; return { 'time': '${takenAt.hour.toString().padLeft(2, '0')}:${takenAt.minute.toString().padLeft(2, '0')}', 'units': unitsTaken, }; }).toList(); return Card( margin: const EdgeInsets.only(bottom: 16), elevation: 3, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: isCompletelyTaken ? Theme.of(context).colorScheme.surface : isTakenToday ? Theme.of(context).colorScheme.secondaryContainer : Theme.of(context).colorScheme.surface, border: Border.all( color: isCompletelyTaken ? Colors.green.shade600 : isTakenToday ? Theme.of(context).colorScheme.secondary : Theme.of(context).colorScheme.outline.withOpacity(0.2), width: 1.5, ), ), child: Theme( data: Theme.of(context).copyWith( dividerColor: Colors.transparent, ), child: ExpansionTile( initiallyExpanded: _isExpanded, onExpansionChanged: (expanded) { setState(() { _isExpanded = expanded; }); }, tilePadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), childrenPadding: const EdgeInsets.fromLTRB(20, 0, 20, 20), leading: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: isCompletelyTaken ? Colors.green.shade500 : isTakenToday ? Theme.of(context).colorScheme.secondary : Theme.of(context).colorScheme.primary.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon( isCompletelyTaken ? Icons.check_circle : isTakenToday ? Icons.schedule : Icons.medication, color: isCompletelyTaken ? Theme.of(context).colorScheme.inverseSurface : isTakenToday ? Theme.of(context).colorScheme.onSecondary : Theme.of(context).colorScheme.primary, size: 20, ), ), title: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( widget.supplement.name, style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: isCompletelyTaken ? Theme.of(context).colorScheme.inverseSurface : isTakenToday ? Theme.of(context).colorScheme.onSecondaryContainer : Theme.of(context).colorScheme.onSurface, ), ), if (widget.supplement.brand != null && widget.supplement.brand!.isNotEmpty) Text( widget.supplement.brand!, style: TextStyle( fontSize: 12, color: isCompletelyTaken ? Colors.green.shade200 : isTakenToday ? Theme.of(context).colorScheme.secondary : Theme.of(context).colorScheme.primary, fontWeight: FontWeight.w500, ), ), ], ), ), // Status badge and take button in collapsed view if (!_isExpanded) ...[ if (isCompletelyTaken) Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Colors.green.shade500, borderRadius: BorderRadius.circular(12), ), child: Text( 'Complete', style: TextStyle( color: Theme.of(context).colorScheme.inverseSurface, fontSize: 10, fontWeight: FontWeight.bold, ), ), ) else ...[ if (isTakenToday) Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), margin: const EdgeInsets.only(right: 8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.secondary, borderRadius: BorderRadius.circular(12), ), child: Text( '$todayIntakeCount/${widget.supplement.frequencyPerDay}', style: TextStyle( color: Theme.of(context).colorScheme.onSecondary, fontSize: 10, fontWeight: FontWeight.bold, ), ), ), ElevatedButton( onPressed: isCompletelyTaken ? null : widget.onTake, style: ElevatedButton.styleFrom( backgroundColor: isCompletelyTaken ? Colors.green.shade500 : Theme.of(context).colorScheme.primary, foregroundColor: Theme.of(context).colorScheme.inverseSurface, padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6), minimumSize: const Size(60, 32), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: Text( isCompletelyTaken ? '✓' : 'Take', style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w600), ), ), ], ], ], ), trailing: PopupMenuButton( padding: EdgeInsets.zero, icon: Icon( Icons.more_vert, color: isCompletelyTaken ? Theme.of(context).colorScheme.inverseSurface : Theme.of(context).colorScheme.onSurfaceVariant, ), onSelected: (value) { switch (value) { case 'edit': widget.onEdit(); break; case 'archive': widget.onArchive(); break; case 'delete': widget.onDelete(); break; } }, itemBuilder: (context) => [ const PopupMenuItem( value: 'edit', child: Row( children: [ Icon(Icons.edit), SizedBox(width: 8), Text('Edit'), ], ), ), const PopupMenuItem( value: 'archive', child: Row( children: [ Icon(Icons.archive, color: Colors.orange), SizedBox(width: 8), Text('Archive'), ], ), ), const PopupMenuItem( value: 'delete', child: Row( children: [ Icon(Icons.delete, color: Colors.red), SizedBox(width: 8), Text('Delete', style: TextStyle(color: Colors.red)), ], ), ), ], ), children: [ // Today's intake times (if any) - only show in expanded view if (todayIntakes.isNotEmpty) ...[ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isCompletelyTaken ? Colors.green.shade700.withOpacity(0.8) : Theme.of(context).colorScheme.secondaryContainer.withOpacity(0.7), borderRadius: BorderRadius.circular(8), border: Border.all( color: isCompletelyTaken ? Colors.green.shade500 : Theme.of(context).colorScheme.secondary, ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.check_circle_outline, size: 16, color: isCompletelyTaken ? Colors.green.shade200 : Theme.of(context).colorScheme.onSecondaryContainer, ), const SizedBox(width: 6), Text( 'Taken today:', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: isCompletelyTaken ? Colors.green.shade200 : Theme.of(context).colorScheme.onSecondaryContainer, ), ), ], ), const SizedBox(height: 6), Wrap( spacing: 8, runSpacing: 4, children: todayIntakes.map((intake) { final units = intake['units'] as double; final unitsText = units == 1.0 ? '${widget.supplement.unitType}' : '${units.toStringAsFixed(units % 1 == 0 ? 0 : 1)} ${widget.supplement.unitType}'; return Container( padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2), decoration: BoxDecoration( color: isCompletelyTaken ? Colors.green.shade600 : Theme.of(context).colorScheme.secondary, borderRadius: BorderRadius.circular(6), ), child: Text( '${intake['time']} • $unitsText', style: TextStyle( fontSize: 10, fontWeight: FontWeight.w500, color: isCompletelyTaken ? Colors.white : Theme.of(context).colorScheme.onSecondary, ), ), ); }).toList(), ), ], ), ), const SizedBox(height: 16), ], // Ingredients section Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.3), borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Ingredients per ${widget.supplement.unitType}:', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 8), Wrap( spacing: 8, runSpacing: 4, children: widget.supplement.ingredients.map((ingredient) { return Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(8), border: Border.all( color: Theme.of(context).colorScheme.primary.withOpacity(0.3), ), ), child: Text( '${ingredient.name} ${ingredient.amount}${ingredient.unit}', style: TextStyle( fontSize: 11, fontWeight: FontWeight.w500, color: Theme.of(context).colorScheme.primary, ), ), ); }).toList(), ), ], ), ), const SizedBox(height: 12), // Schedule and dosage info Row( children: [ Expanded( child: _InfoChip( icon: Icons.schedule, label: '${widget.supplement.frequencyPerDay}x daily', context: context, ), ), const SizedBox(width: 8), Expanded( child: _InfoChip( icon: Icons.medication, label: '${widget.supplement.numberOfUnits} ${widget.supplement.unitType}', context: context, ), ), ], ), if (widget.supplement.reminderTimes.isNotEmpty) ...[ const SizedBox(height: 8), _InfoChip( icon: Icons.notifications, label: 'Reminders: ${widget.supplement.reminderTimes.join(', ')}', context: context, fullWidth: true, ), ], if (widget.supplement.notes != null && widget.supplement.notes!.isNotEmpty) ...[ const SizedBox(height: 8), Container( width: double.infinity, padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.2), borderRadius: BorderRadius.circular(8), ), child: Text( widget.supplement.notes!, style: TextStyle( fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant, fontStyle: FontStyle.italic, ), ), ), ], const SizedBox(height: 16), // Take button SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: isCompletelyTaken ? null : widget.onTake, icon: Icon( isCompletelyTaken ? Icons.check_circle : Icons.medication, size: 18, ), label: Text( isCompletelyTaken ? 'All doses taken today' : isTakenToday ? 'Take next dose' : 'Take supplement', style: const TextStyle(fontWeight: FontWeight.w600), ), style: ElevatedButton.styleFrom( backgroundColor: isCompletelyTaken ? Colors.green.shade500 : Theme.of(context).colorScheme.primary, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(vertical: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), elevation: isCompletelyTaken ? 0 : 2, ), ), ), ], ), ), ), ); }, ); } } class _InfoChip extends StatelessWidget { final IconData icon; final String label; final BuildContext context; final bool fullWidth; const _InfoChip({ required this.icon, required this.label, required this.context, this.fullWidth = false, }); @override Widget build(BuildContext context) { return Container( width: fullWidth ? double.infinity : null, padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 6), decoration: BoxDecoration( color: Theme.of(context).colorScheme.surfaceVariant.withOpacity(0.4), borderRadius: BorderRadius.circular(8), ), child: Row( mainAxisSize: fullWidth ? MainAxisSize.max : MainAxisSize.min, children: [ Icon( icon, size: 14, color: Theme.of(context).colorScheme.onSurfaceVariant, ), const SizedBox(width: 4), Flexible( child: Text( label, style: TextStyle( fontSize: 11, color: Theme.of(context).colorScheme.onSurfaceVariant, fontWeight: FontWeight.w500, ), overflow: TextOverflow.ellipsis, ), ), ], ), ); } }