import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; import '../../theme/app_theme.dart'; import '../../models/user_profile.dart'; import '../../providers/user_provider.dart'; import '../../services/notification_service.dart'; import '../../widgets/pad_settings_dialog.dart'; // We can reuse the logic, but maybe embed it directly or just link it. // Actually, let's rebuild the UI here properly as a screen instead of a dialog, // or for now, since we already have the dialog logic working well, let's just // have this screen trigger the dialog or embed the same widgets. // However, the user asked to "make a new setting page", so a full screen is better. // I'll copy the logic from the dialog into this screen for a seamless experience. class SuppliesSettingsScreen extends ConsumerStatefulWidget { const SuppliesSettingsScreen({super.key}); @override ConsumerState createState() => _SuppliesSettingsScreenState(); } class _SuppliesSettingsScreenState extends ConsumerState { bool _isTrackingEnabled = false; int _typicalFlow = 2; bool _isAutoInventoryEnabled = true; bool _showPadTimerMinutes = true; bool _showPadTimerSeconds = false; // Inventory List _supplies = []; int _lowInventoryThreshold = 5; @override void initState() { super.initState(); final user = ref.read(userProfileProvider); if (user != null) { _isTrackingEnabled = user.isPadTrackingEnabled; _typicalFlow = user.typicalFlowIntensity ?? 2; _isAutoInventoryEnabled = user.isAutoInventoryEnabled; _lowInventoryThreshold = user.lowInventoryThreshold; _showPadTimerMinutes = user.showPadTimerMinutes; _showPadTimerSeconds = user.showPadTimerSeconds; // Load supplies if (user.padSupplies != null) { _supplies = List.from(user.padSupplies!); } } } Future _saveSettings() async { final user = ref.read(userProfileProvider); if (user != null) { // Calculate total inventory count for the legacy field int totalCount = _supplies.fold(0, (sum, item) => sum + item.count); final updatedProfile = user.copyWith( isPadTrackingEnabled: _isTrackingEnabled, typicalFlowIntensity: _typicalFlow, isAutoInventoryEnabled: _isAutoInventoryEnabled, showPadTimerMinutes: _showPadTimerMinutes, showPadTimerSeconds: _showPadTimerSeconds, padSupplies: _supplies, padInventoryCount: totalCount, lowInventoryThreshold: _lowInventoryThreshold, ); await ref.read(userProfileProvider.notifier).updateProfile(updatedProfile); // Check for Low Supply Alert if (updatedProfile.notifyLowSupply && totalCount <= updatedProfile.lowInventoryThreshold) { NotificationService().showLocalNotification( id: 2001, title: 'Low Pad Supply', body: 'Your inventory is low ($totalCount left). Time to restock!', ); } if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Preferences saved')), ); } } } void _addOrEditSupply({SupplyItem? item, int? index}) { showDialog( context: context, builder: (context) => _SupplyDialog( initialItem: item, onSave: (newItem) { setState(() { if (index != null) { _supplies[index] = newItem; } else { _supplies.add(newItem); } }); }, ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Period Supplies'), actions: [ IconButton( icon: const Icon(Icons.save), onPressed: _saveSettings, ) ], ), body: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Toggle Row( children: [ Expanded( child: Text( 'Enable Pad Tracking', style: GoogleFonts.outfit( fontSize: 18, fontWeight: FontWeight.w600, color: AppColors.charcoal, ), ), ), Switch( value: _isTrackingEnabled, onChanged: (val) => setState(() => _isTrackingEnabled = val), activeColor: AppColors.menstrualPhase, ), ], ), if (_isTrackingEnabled) ...[ const Divider(height: 32), // Inventory Section Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( 'My Inventory', style: GoogleFonts.outfit( fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.warmGray, ), ), TextButton.icon( onPressed: () => _addOrEditSupply(), icon: const Icon(Icons.add), label: const Text('Add Item'), style: TextButton.styleFrom(foregroundColor: AppColors.menstrualPhase), ), ], ), const SizedBox(height: 8), if (_supplies.isEmpty) Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.grey.withOpacity(0.1), borderRadius: BorderRadius.circular(12), ), child: Center( child: Text( 'No supplies added yet.\nAdd items to track specific inventory.', textAlign: TextAlign.center, style: GoogleFonts.outfit(color: AppColors.warmGray), ), ), ) else ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: _supplies.length, separatorBuilder: (c, i) => const SizedBox(height: 8), itemBuilder: (context, index) { final item = _supplies[index]; return ListTile( tileColor: Theme.of(context).cardTheme.color, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), side: BorderSide(color: Colors.black.withOpacity(0.05)), ), leading: CircleAvatar( backgroundColor: AppColors.menstrualPhase.withOpacity(0.1), child: Text( item.count.toString(), style: GoogleFonts.outfit( fontWeight: FontWeight.bold, color: AppColors.menstrualPhase, ), ), ), title: Text(item.brand, style: GoogleFonts.outfit(fontWeight: FontWeight.w600)), subtitle: Text(item.type.label, style: GoogleFonts.outfit(fontSize: 12)), trailing: IconButton( icon: const Icon(Icons.delete_outline, color: Colors.red), onPressed: () { setState(() { _supplies.removeAt(index); }); }, ), onTap: () => _addOrEditSupply(item: item, index: index), ); }, ), const Divider(height: 32), // Typical Flow Text( 'Typical Flow Intensity', style: GoogleFonts.outfit( fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.warmGray, ), ), const SizedBox(height: 8), Row( children: [ Text('Light', style: GoogleFonts.outfit(fontSize: 12, color: AppColors.warmGray)), Expanded( child: Slider( value: _typicalFlow.toDouble(), min: 1, max: 5, divisions: 4, activeColor: AppColors.menstrualPhase, onChanged: (val) => setState(() => _typicalFlow = val.round()), ), ), Text('Heavy', style: GoogleFonts.outfit(fontSize: 12, color: AppColors.warmGray)), ], ), Center( child: Text( '$_typicalFlow/5', style: GoogleFonts.outfit( fontWeight: FontWeight.bold, color: AppColors.menstrualPhase ) ), ), const SizedBox(height: 24), // Auto Deduct Toggle SwitchListTile( contentPadding: EdgeInsets.zero, title: Text( 'Auto-deduct on Log', style: GoogleFonts.outfit(fontWeight: FontWeight.w500, color: AppColors.charcoal), ), subtitle: Text( 'Reduce count when you log a pad', style: GoogleFonts.outfit(fontSize: 12, color: AppColors.warmGray), ), value: _isAutoInventoryEnabled, onChanged: (val) => setState(() => _isAutoInventoryEnabled = val), activeColor: AppColors.menstrualPhase, ), const Divider(height: 32), Text( 'Timer Display Settings', style: GoogleFonts.outfit( fontSize: 16, fontWeight: FontWeight.w500, color: AppColors.warmGray, ), ), const SizedBox(height: 8), SwitchListTile( contentPadding: EdgeInsets.zero, title: Text( 'Show Minutes', style: GoogleFonts.outfit(fontWeight: FontWeight.w500, color: AppColors.charcoal), ), value: _showPadTimerMinutes, onChanged: (val) { setState(() { _showPadTimerMinutes = val; if (!val) { _showPadTimerSeconds = false; } }); }, activeColor: AppColors.menstrualPhase, ), SwitchListTile( contentPadding: EdgeInsets.zero, title: Text( 'Show Seconds', style: GoogleFonts.outfit( fontWeight: FontWeight.w500, color: _showPadTimerMinutes ? AppColors.charcoal : AppColors.warmGray ), ), value: _showPadTimerSeconds, onChanged: _showPadTimerMinutes ? (val) => setState(() => _showPadTimerSeconds = val) : null, activeColor: AppColors.menstrualPhase, ), ], ], ), ), ); } } class _SupplyDialog extends StatefulWidget { final SupplyItem? initialItem; final Function(SupplyItem) onSave; const _SupplyDialog({this.initialItem, required this.onSave}); @override State<_SupplyDialog> createState() => _SupplyDialogState(); } class _SupplyDialogState extends State<_SupplyDialog> { late TextEditingController _brandController; late PadType _type; late int _count; @override void initState() { super.initState(); _brandController = TextEditingController(text: widget.initialItem?.brand ?? ''); _type = widget.initialItem?.type ?? PadType.regular; _count = widget.initialItem?.count ?? 0; } @override void dispose() { _brandController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return AlertDialog( title: Text(widget.initialItem == null ? 'Add Supply' : 'Edit Supply'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: _brandController, decoration: const InputDecoration(labelText: 'Brand / Name'), textCapitalization: TextCapitalization.sentences, ), const SizedBox(height: 16), DropdownButtonFormField( value: _type, items: PadType.values.map((t) => DropdownMenuItem( value: t, child: Text(t.label), )).toList(), onChanged: (val) => setState(() => _type = val!), decoration: const InputDecoration(labelText: 'Type'), ), const SizedBox(height: 16), TextField( keyboardType: TextInputType.number, decoration: const InputDecoration(labelText: 'Quantity'), controller: TextEditingController(text: _count.toString()), // Hacky for demo, binding needed properly onChanged: (val) => _count = int.tryParse(val) ?? 0, ), ], ), ), actions: [ TextButton(onPressed: () => Navigator.pop(context), child: const Text('Cancel')), ElevatedButton( onPressed: () { if (_brandController.text.isEmpty) return; final newItem = SupplyItem( brand: _brandController.text.trim(), type: _type, absorbency: 3, // Default for now count: _count, ); widget.onSave(newItem); Navigator.pop(context); }, child: const Text('Save'), ), ], ); } }