import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../providers/settings_provider.dart'; import '../providers/supplement_provider.dart'; import '../services/notification_service.dart'; import 'pending_notifications_screen.dart'; import 'sync_settings_screen.dart'; class SettingsScreen extends StatelessWidget { const SettingsScreen({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Settings'), ), body: Consumer( builder: (context, settingsProvider, child) { return ListView( padding: const EdgeInsets.all(16.0), children: [ Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Theme', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 16), RadioListTile( title: const Text('Follow System'), subtitle: const Text('Use system theme setting'), value: ThemeOption.system, groupValue: settingsProvider.themeOption, onChanged: (value) { if (value != null) { settingsProvider.setThemeOption(value); } }, ), RadioListTile( title: const Text('Light Theme'), subtitle: const Text('Always use light theme'), value: ThemeOption.light, groupValue: settingsProvider.themeOption, onChanged: (value) { if (value != null) { settingsProvider.setThemeOption(value); } }, ), RadioListTile( title: const Text('Dark Theme'), subtitle: const Text('Always use dark theme'), value: ThemeOption.dark, groupValue: settingsProvider.themeOption, onChanged: (value) { if (value != null) { settingsProvider.setThemeOption(value); } }, ), ], ), ), ), const SizedBox(height: 16), Card( child: ListTile( leading: const Icon(Icons.cloud_sync), title: const Text('Cloud Sync'), subtitle: const Text('Configure WebDAV sync settings'), trailing: const Icon(Icons.chevron_right), onTap: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const SyncSettingsScreen(), ), ); }, ), ), const SizedBox(height: 16), Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Time Periods', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 8), Text( 'Customize when morning, afternoon, evening, and night periods occur', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 16), _TimeRangeSelector( title: 'Morning', icon: Icons.wb_sunny, color: Colors.orange, startHour: settingsProvider.morningStart, endHour: settingsProvider.morningEnd, onChanged: (start, end) => _updateTimeRanges( context, settingsProvider, morningStart: start, morningEnd: end, ), ), const SizedBox(height: 12), _TimeRangeSelector( title: 'Afternoon', icon: Icons.light_mode, color: Colors.blue, startHour: settingsProvider.afternoonStart, endHour: settingsProvider.afternoonEnd, onChanged: (start, end) => _updateTimeRanges( context, settingsProvider, afternoonStart: start, afternoonEnd: end, ), ), const SizedBox(height: 12), _TimeRangeSelector( title: 'Evening', icon: Icons.nightlight_round, color: Colors.indigo, startHour: settingsProvider.eveningStart, endHour: settingsProvider.eveningEnd, onChanged: (start, end) => _updateTimeRanges( context, settingsProvider, eveningStart: start, eveningEnd: end, ), ), const SizedBox(height: 12), _TimeRangeSelector( title: 'Night', icon: Icons.bedtime, color: Colors.purple, startHour: settingsProvider.nightStart, endHour: settingsProvider.nightEnd, onChanged: (start, end) => _updateTimeRanges( context, settingsProvider, nightStart: start, nightEnd: end, ), ), ], ), ), ), const SizedBox(height: 16), Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.notifications_active, color: Colors.blue), const SizedBox(width: 8), Text( 'Persistent Reminders', style: Theme.of(context).textTheme.titleMedium, ), ], ), const SizedBox(height: 8), Text( 'Configure automatic reminder retries for ignored notifications', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 16), SwitchListTile( title: const Text('Enable Persistent Reminders'), subtitle: const Text('Resend notifications if ignored'), value: settingsProvider.persistentReminders, onChanged: (value) { settingsProvider.setPersistentReminders(value); }, ), if (settingsProvider.persistentReminders) ...[ const SizedBox(height: 16), Text( 'Retry Interval', style: Theme.of(context).textTheme.titleSmall, ), const SizedBox(height: 8), SegmentedButton( segments: const [ ButtonSegment(value: 5, label: Text('5 min')), ButtonSegment(value: 10, label: Text('10 min')), ButtonSegment(value: 15, label: Text('15 min')), ButtonSegment(value: 30, label: Text('30 min')), ], selected: {settingsProvider.reminderRetryInterval}, onSelectionChanged: (values) { settingsProvider.setReminderRetryInterval(values.first); }, ), const SizedBox(height: 16), Text( 'Maximum Retry Attempts', style: Theme.of(context).textTheme.titleSmall, ), const SizedBox(height: 8), SegmentedButton( segments: const [ ButtonSegment(value: 1, label: Text('1')), ButtonSegment(value: 2, label: Text('2')), ButtonSegment(value: 3, label: Text('3')), ButtonSegment(value: 4, label: Text('4')), ButtonSegment(value: 5, label: Text('5')), ], selected: {settingsProvider.maxRetryAttempts}, onSelectionChanged: (values) { settingsProvider.setMaxRetryAttempts(values.first); }, ), ], ], ), ), ), const SizedBox(height: 16), Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ const Icon(Icons.notifications_outlined), const SizedBox(width: 8), Text( 'Notifications', style: Theme.of(context).textTheme.titleMedium, ), ], ), const SizedBox(height: 8), Text( 'View and manage pending notifications', style: Theme.of(context).textTheme.bodySmall?.copyWith( color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 16), SizedBox( width: double.infinity, child: ElevatedButton.icon( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const PendingNotificationsScreen(), ), ); }, icon: const Icon(Icons.list), label: const Text('View Pending Notifications'), ), ), ], ), ), ), const SizedBox(height: 16), if (Theme.of(context).brightness == Brightness.dark) // Only show in debug mode for now Card( child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(Icons.bug_report, color: Colors.orange), const SizedBox(width: 8), Text( 'Debug - Notifications', style: Theme.of(context).textTheme.titleMedium, ), ], ), const SizedBox(height: 16), Consumer( builder: (context, supplementProvider, child) { return Column( children: [ ElevatedButton.icon( onPressed: () async { await supplementProvider.testNotifications(); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Test notification sent!')), ); } }, icon: const Icon(Icons.notifications_active), label: const Text('Test Instant'), ), const SizedBox(height: 8), ElevatedButton.icon( onPressed: () async { await supplementProvider.testScheduledNotification(); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Scheduled test notification for 1 minute from now!')), ); } }, icon: const Icon(Icons.schedule), label: const Text('Test Scheduled (1min)'), ), const SizedBox(height: 8), ElevatedButton.icon( onPressed: () async { await supplementProvider.testNotificationActions(); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Test notification with actions sent! Try the Take/Snooze buttons.')), ); } }, icon: const Icon(Icons.touch_app), label: const Text('Test Actions'), ), const SizedBox(height: 8), ElevatedButton.icon( onPressed: () async { await NotificationService().testBasicNotification(); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Basic test notification sent! Tap it to test callback.')), ); } }, icon: const Icon(Icons.tap_and_play), label: const Text('Test Basic Tap'), ), const SizedBox(height: 8), ElevatedButton.icon( onPressed: () async { await supplementProvider.rescheduleAllNotifications(); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('All notifications rescheduled!')), ); } }, icon: const Icon(Icons.refresh), label: const Text('Reschedule All'), ), const SizedBox(height: 8), ElevatedButton.icon( onPressed: () async { await supplementProvider.cancelAllNotifications(); if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('All notifications cancelled!')), ); } }, icon: const Icon(Icons.cancel), label: const Text('Cancel All'), ), const SizedBox(height: 8), ElevatedButton.icon( onPressed: () async { final pending = await supplementProvider.getPendingNotifications(); if (context.mounted) { showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Pending Notifications'), content: pending.isEmpty ? const Text('No pending notifications') : SizedBox( width: double.maxFinite, child: Consumer( builder: (context, provider, child) { return ListView.builder( shrinkWrap: true, itemCount: pending.length, itemBuilder: (context, index) { final notification = pending[index]; // Calculate scheduled time inline String scheduledTime = ''; try { final notificationId = notification.id; if (notificationId == 99999) { scheduledTime = 'Test notification'; } else if (notificationId > 1000) { final snoozeMinutes = notificationId % 1000; scheduledTime = 'Snoozed ($snoozeMinutes min)'; } else { final supplementId = notificationId ~/ 100; final reminderIndex = notificationId % 100; final supplement = provider.supplements.firstWhere( (s) => s.id == supplementId, orElse: () => provider.supplements.first, ); if (reminderIndex < supplement.reminderTimes.length) { final reminderTime = supplement.reminderTimes[reminderIndex]; final now = DateTime.now(); final timeParts = reminderTime.split(':'); final hour = int.parse(timeParts[0]); final minute = int.parse(timeParts[1]); final today = DateTime(now.year, now.month, now.day, hour, minute); final isToday = today.isAfter(now); scheduledTime = '${isToday ? 'Today' : 'Tomorrow'} at $reminderTime'; } else { scheduledTime = 'Unknown time'; } } } catch (e) { scheduledTime = 'ID: ${notification.id}'; } return Card( margin: const EdgeInsets.symmetric(vertical: 4), child: ListTile( leading: CircleAvatar( backgroundColor: Theme.of(context).colorScheme.primary, child: Text( '${index + 1}', style: TextStyle( color: Theme.of(context).colorScheme.onPrimary, fontWeight: FontWeight.bold, ), ), ), title: Text( notification.title ?? 'No title', style: const TextStyle(fontWeight: FontWeight.w600), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('ID: ${notification.id}'), Text(notification.body ?? 'No body'), if (scheduledTime.isNotEmpty) ...[ const SizedBox(height: 4), Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primaryContainer, borderRadius: BorderRadius.circular(12), ), child: Text( '⏰ $scheduledTime', style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: Theme.of(context).colorScheme.onPrimaryContainer, ), ), ), ], ], ), isThreeLine: true, ), ); }, ); }, ), ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: const Text('Close'), ), ], ), ); } }, icon: const Icon(Icons.list), label: const Text('Show Pending'), ), ], ); }, ), ], ), ), ), ], ); }, ), ); } void _updateTimeRanges( BuildContext context, SettingsProvider settingsProvider, { int? morningStart, int? morningEnd, int? afternoonStart, int? afternoonEnd, int? eveningStart, int? eveningEnd, int? nightStart, int? nightEnd, }) async { try { await settingsProvider.setTimeRanges( morningStart: morningStart ?? settingsProvider.morningStart, morningEnd: morningEnd ?? settingsProvider.morningEnd, afternoonStart: afternoonStart ?? settingsProvider.afternoonStart, afternoonEnd: afternoonEnd ?? settingsProvider.afternoonEnd, eveningStart: eveningStart ?? settingsProvider.eveningStart, eveningEnd: eveningEnd ?? settingsProvider.eveningEnd, nightStart: nightStart ?? settingsProvider.nightStart, nightEnd: nightEnd ?? settingsProvider.nightEnd, ); } catch (e) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Invalid time ranges: ${e.toString()}'), backgroundColor: Colors.red, ), ); } } } } class _TimeRangeSelector extends StatelessWidget { final String title; final IconData icon; final Color color; final int startHour; final int endHour; final void Function(int start, int end) onChanged; const _TimeRangeSelector({ required this.title, required this.icon, required this.color, required this.startHour, required this.endHour, required this.onChanged, }); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: color.withOpacity(0.1), borderRadius: BorderRadius.circular(8), border: Border.all(color: color.withOpacity(0.3)), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon(icon, color: color, size: 20), const SizedBox(width: 8), Text( title, style: TextStyle( fontWeight: FontWeight.bold, color: color, fontSize: 16, ), ), const Spacer(), Text( '${_formatHour(startHour)} - ${_formatHour(endHour + 1)}', style: TextStyle( color: color, fontSize: 12, fontWeight: FontWeight.w500, ), ), ], ), const SizedBox(height: 12), Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Start: ${_formatHour(startHour)}', style: const TextStyle(fontSize: 12), ), Slider( value: startHour.toDouble(), min: 0, max: 23, divisions: 23, activeColor: color, onChanged: (value) { final newStart = value.round(); if (newStart != endHour) { onChanged(newStart, endHour); } }, ), ], ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'End: ${_formatHour(endHour)}', style: const TextStyle(fontSize: 12), ), Slider( value: endHour.toDouble(), min: 0, max: 23, divisions: 23, activeColor: color, onChanged: (value) { final newEnd = value.round(); if (newEnd != startHour) { onChanged(startHour, newEnd); } }, ), ], ), ), ], ), ], ), ); } String _formatHour(int hour) { final adjustedHour = hour % 24; return '${adjustedHour.toString().padLeft(2, '0')}:00'; } }