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 '../../models/cycle_entry.dart'; import '../../models/scripture.dart'; import '../calendar/calendar_screen.dart'; import '../log/log_screen.dart'; import '../log/pad_tracker_screen.dart'; import '../devotional/devotional_screen.dart'; import '../settings/appearance_screen.dart'; import '../settings/cycle_settings_screen.dart'; import '../settings/relationship_settings_screen.dart'; import '../settings/goal_settings_screen.dart'; import '../settings/cycle_history_screen.dart'; import '../settings/sharing_settings_screen.dart'; import '../settings/notification_settings_screen.dart'; import '../settings/privacy_settings_screen.dart'; import '../settings/supplies_settings_screen.dart'; import '../settings/export_data_screen.dart'; import '../learn/wife_learn_screen.dart'; import '../../widgets/tip_card.dart'; import '../../widgets/cycle_ring.dart'; import '../../widgets/scripture_card.dart'; import '../../widgets/pad_tracker_card.dart'; import '../../widgets/quick_log_buttons.dart'; import '../../providers/user_provider.dart'; import '../../providers/navigation_provider.dart'; import '../../services/cycle_service.dart'; import '../../services/bible_utils.dart'; import '../../providers/scripture_provider.dart'; class HomeScreen extends ConsumerWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final selectedIndex = ref.watch(navigationProvider); final isPadTrackingEnabled = ref.watch(userProfileProvider.select((u) => u?.isPadTrackingEnabled ?? false)); final List tabs; final List navBarItems; if (isPadTrackingEnabled) { tabs = [ const _DashboardTab(), const CalendarScreen(), const PadTrackerScreen(), const LogScreen(), const DevotionalScreen(), const WifeLearnScreen(), _SettingsTab(onReset: () => ref.read(navigationProvider.notifier).setIndex(0)), ]; navBarItems = [ const BottomNavigationBarItem(icon: Icon(Icons.home_outlined), activeIcon: Icon(Icons.home), label: 'Home'), const BottomNavigationBarItem(icon: Icon(Icons.calendar_today_outlined), activeIcon: Icon(Icons.calendar_today), label: 'Calendar'), const BottomNavigationBarItem(icon: Icon(Icons.inventory_2_outlined), activeIcon: Icon(Icons.inventory_2), label: 'Supplies'), const BottomNavigationBarItem(icon: Icon(Icons.add_circle_outline), activeIcon: Icon(Icons.add_circle), label: 'Log'), const BottomNavigationBarItem(icon: Icon(Icons.menu_book_outlined), activeIcon: Icon(Icons.menu_book), label: 'Devotional'), const BottomNavigationBarItem(icon: Icon(Icons.school_outlined), activeIcon: Icon(Icons.school), label: 'Learn'), const BottomNavigationBarItem(icon: Icon(Icons.settings_outlined), activeIcon: Icon(Icons.settings), label: 'Settings'), ]; } else { tabs = [ const _DashboardTab(), const CalendarScreen(), const DevotionalScreen(), const LogScreen(), const WifeLearnScreen(), _SettingsTab(onReset: () => ref.read(navigationProvider.notifier).setIndex(0)), ]; navBarItems = [ const BottomNavigationBarItem(icon: Icon(Icons.home_outlined), activeIcon: Icon(Icons.home), label: 'Home'), const BottomNavigationBarItem(icon: Icon(Icons.calendar_today_outlined), activeIcon: Icon(Icons.calendar_today), label: 'Calendar'), const BottomNavigationBarItem(icon: Icon(Icons.menu_book_outlined), activeIcon: Icon(Icons.menu_book), label: 'Devotional'), const BottomNavigationBarItem(icon: Icon(Icons.add_circle_outline), activeIcon: Icon(Icons.add_circle), label: 'Log'), const BottomNavigationBarItem(icon: Icon(Icons.school_outlined), activeIcon: Icon(Icons.school), label: 'Learn'), const BottomNavigationBarItem(icon: Icon(Icons.settings_outlined), activeIcon: Icon(Icons.settings), label: 'Settings'), ]; } return Scaffold( body: IndexedStack( index: selectedIndex >= tabs.length ? 0 : selectedIndex, children: tabs, ), bottomNavigationBar: Container( decoration: BoxDecoration( color: Theme.of(context).bottomNavigationBarTheme.backgroundColor, boxShadow: [ BoxShadow( color: (Theme.of(context).brightness == Brightness.dark ? Colors.black : AppColors.charcoal) .withOpacity(0.1), blurRadius: 10, offset: const Offset(0, -2), ), ], ), child: BottomNavigationBar( currentIndex: selectedIndex >= tabs.length ? 0 : selectedIndex, onTap: (index) => ref.read(navigationProvider.notifier).setIndex(index), items: navBarItems, ), ), ); } } class _DashboardTab extends ConsumerStatefulWidget { const _DashboardTab({super.key}); @override ConsumerState<_DashboardTab> createState() => _DashboardTabState(); } class _DashboardTabState extends ConsumerState<_DashboardTab> { @override void initState() { super.initState(); _initializeScripture(); } // This method initializes the scripture and can react to phase changes. // It's called from initState and also when currentCycleInfoProvider changes. Future _initializeScripture() async { final phase = ref.read(currentCycleInfoProvider).phase; await ref.read(scriptureProvider.notifier).initializeScripture(phase); } @override Widget build(BuildContext context) { // Listen for changes in the cycle info to re-initialize scripture if needed ref.listen(currentCycleInfoProvider, (previousCycleInfo, newCycleInfo) { if (previousCycleInfo?.phase != newCycleInfo.phase) { _initializeScripture(); } }); final name = ref.watch(userProfileProvider.select((u) => u?.name)) ?? 'Friend'; final translation = ref.watch(userProfileProvider.select((u) => u?.bibleTranslation)) ?? BibleTranslation.esv; final role = ref.watch(userProfileProvider.select((u) => u?.role)) ?? UserRole.wife; final isMarried = ref.watch(userProfileProvider.select((u) => u?.isMarried)) ?? false; final averageCycleLength = ref.watch(userProfileProvider.select((u) => u?.averageCycleLength)) ?? 28; final cycleInfo = ref.watch(currentCycleInfoProvider); final phase = cycleInfo.phase; final dayOfCycle = cycleInfo.dayOfCycle; // Watch the scripture provider for the current scripture final scriptureState = ref.watch(scriptureProvider); final scripture = scriptureState.currentScripture; final maxIndex = scriptureState.maxIndex; if (scripture == null) { return const Center(child: CircularProgressIndicator()); // Or some error message } return SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildGreeting(context, name), const SizedBox(height: 24), Center( child: CycleRing( dayOfCycle: dayOfCycle, totalDays: averageCycleLength, phase: phase, ), ), if (phase == CyclePhase.menstrual) ...[ const SizedBox(height: 24), const PadTrackerCard(), ], const SizedBox(height: 32), // Main Scripture Card with Navigation Stack( alignment: Alignment.center, children: [ ScriptureCard( verse: scripture.getVerse(translation), reference: scripture.reference, translation: translation.label, phase: phase, onTranslationTap: () => BibleUtils.showTranslationPicker(context, ref), ), if (maxIndex != null && maxIndex > 1) ...[ Positioned( left: 0, child: IconButton( icon: Icon(Icons.arrow_back_ios), onPressed: () => ref.read(scriptureProvider.notifier).getPreviousScripture(), color: AppColors.charcoal, ), ), Positioned( right: 0, child: IconButton( icon: Icon(Icons.arrow_forward_ios), onPressed: () => ref.read(scriptureProvider.notifier).getNextScripture(), color: AppColors.charcoal, ), ), ], ], ), const SizedBox(height: 16), if (maxIndex != null && maxIndex > 1) Center( child: TextButton.icon( onPressed: () => ref.read(scriptureProvider.notifier).getRandomScripture(), icon: const Icon(Icons.shuffle), label: const Text('Random Verse'), style: TextButton.styleFrom( foregroundColor: Theme.of(context).colorScheme.primary, ), ), ), const SizedBox(height: 24), Text( 'Quick Log', style: Theme.of(context).textTheme.titleLarge?.copyWith( fontSize: 18, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 12), const QuickLogButtons(), const SizedBox(height: 24), if (role == UserRole.wife) _buildWifeTipsSection(context), const SizedBox(height: 20), ], ), ), ); } Widget _buildGreeting(BuildContext context, String name) { final theme = Theme.of(context); final hour = DateTime.now().hour; String greeting; if (hour < 12) { greeting = 'Good morning'; } else if (hour < 17) { greeting = 'Good afternoon'; } else { greeting = 'Good evening'; } return Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '$greeting,', style: GoogleFonts.outfit( fontSize: 16, color: theme.colorScheme.onSurfaceVariant, ), ), Text( name, style: theme.textTheme.displaySmall?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), ], ), ), Container( width: 48, height: 48, decoration: BoxDecoration( color: theme.colorScheme.primaryContainer.withOpacity(0.5), borderRadius: BorderRadius.circular(12), ), child: Icon( Icons.notifications_outlined, color: theme.colorScheme.primary, ), ), ], ); } } class _SettingsTab extends ConsumerWidget { final VoidCallback? onReset; const _SettingsTab({this.onReset}); Widget _buildSettingsTile(BuildContext context, IconData icon, String title, {VoidCallback? onTap}) { return ListTile( leading: Icon(icon, color: Theme.of(context).colorScheme.onSurface.withOpacity(0.8)), title: Text( title, style: Theme.of(context).textTheme.bodyLarge?.copyWith( fontSize: 16, ), ), trailing: const Icon(Icons.chevron_right, color: AppColors.lightGray), onTap: onTap ?? () { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Settings coming soon!')), ); }, ); } Future _resetApp(BuildContext context, WidgetRef ref) async { final confirmed = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Reset App?'), content: const Text( 'This will clear all data and return you to onboarding. Are you sure?'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text('Cancel')), TextButton( onPressed: () => Navigator.pop(context, true), child: const Text('Reset', style: TextStyle(color: Colors.red)), ), ], ), ); if (confirmed == true) { await ref.read(userProfileProvider.notifier).clearProfile(); await ref.read(cycleEntriesProvider.notifier).clearEntries(); if (context.mounted) { onReset?.call(); Navigator.of(context).pushNamedAndRemoveUntil('/', (route) => false); } } } @override Widget build(BuildContext context, WidgetRef ref) { final name = ref.watch(userProfileProvider.select((u) => u?.name)) ?? 'Guest'; final roleSymbol = ref.watch(userProfileProvider.select((u) => u?.role)) == UserRole.husband ? 'HUSBAND' : null; final relationshipStatus = ref.watch(userProfileProvider .select((u) => u?.relationshipStatus.name.toUpperCase())) ?? 'SINGLE'; final translationLabel = ref.watch(userProfileProvider.select((u) => u?.bibleTranslation.label)) ?? 'ESV'; final isSingle = ref.watch(userProfileProvider.select((u) => u?.relationshipStatus == RelationshipStatus.single)); return SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Settings', style: Theme.of(context).textTheme.displayMedium?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: Theme.of(context).colorScheme.onSurface, ), ), const SizedBox(height: 24), Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Theme.of(context).cardTheme.color, borderRadius: BorderRadius.circular(16), border: Border.all( color: Theme.of(context).colorScheme.outline.withOpacity(0.05)), ), child: Row( children: [ Container( width: 60, height: 60, decoration: BoxDecoration( gradient: LinearGradient( colors: [ Theme.of(context).colorScheme.primary.withOpacity(0.7), Theme.of(context).colorScheme.secondary.withOpacity(0.7) ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(16), ), child: Center( child: Text( name.isNotEmpty ? name[0].toUpperCase() : '?', style: GoogleFonts.outfit( fontSize: 24, fontWeight: FontWeight.w600, color: Colors.white, ), ), ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( name, style: Theme.of(context).textTheme.titleLarge?.copyWith( fontSize: 18, fontWeight: FontWeight.w600, ), ), Text( roleSymbol ?? relationshipStatus, style: GoogleFonts.outfit( fontSize: 12, letterSpacing: 1, color: AppColors.warmGray, ), ), ], ), ), const Icon(Icons.chevron_right, color: AppColors.warmGray), ], ), ), const SizedBox(height: 24), _buildSettingsGroup(context, 'Preferences', [ _buildSettingsTile( context, Icons.notifications_outlined, 'Notifications', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const NotificationSettingsScreen())); }, ), _buildSettingsTile( context, Icons.inventory_2_outlined, 'Period Supplies', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SuppliesSettingsScreen())); }, ), _buildSettingsTile( context, Icons.favorite_outline, // Use a different icon for Relationship 'Relationship Status', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const RelationshipSettingsScreen())); }, ), _buildSettingsTile( context, Icons.flag_outlined, 'Cycle Goal', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const GoalSettingsScreen())); }, ), _buildSettingsTile( context, Icons.book_outlined, 'Bible Version ($translationLabel)', onTap: () => BibleUtils.showTranslationPicker(context, ref), ), _buildSettingsTile(context, Icons.palette_outlined, 'Appearance', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const AppearanceScreen())); }), _buildSettingsTile( context, Icons.favorite_border, 'My Favorites', onTap: () => _showFavoritesDialog(context, ref), ), _buildSettingsTile( context, Icons.security, 'Privacy & Security', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const PrivacySettingsScreen())); }), if (!isSingle) _buildSettingsTile( context, Icons.share_outlined, 'Share with Husband', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const SharingSettingsScreen())); }, ), ]), const SizedBox(height: 16), _buildSettingsGroup(context, 'Cycle', [ _buildSettingsTile( context, Icons.calendar_today_outlined, 'Cycle Settings', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const CycleSettingsScreen())); }), _buildSettingsTile( context, Icons.trending_up_outlined, 'Cycle History', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => CycleHistoryScreen())); }), _buildSettingsTile( context, Icons.download_outlined, 'Export Data', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => const ExportDataScreen())); }), ]), const SizedBox(height: 16), _buildSettingsGroup(context, 'Account', [ _buildSettingsTile(context, Icons.logout, 'Reset App / Logout', onTap: () => _resetApp(context, ref)), ]), const SizedBox(height: 16), ], ), ), ); } Widget _buildSettingsGroup( BuildContext context, String title, List tiles) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: GoogleFonts.outfit( fontSize: 14, fontWeight: FontWeight.w500, color: AppColors.warmGray, letterSpacing: 0.5, ), ), const SizedBox(height: 8), Container( decoration: BoxDecoration( color: Theme.of(context).cardTheme.color, borderRadius: BorderRadius.circular(12), border: Border.all( color: Theme.of(context).colorScheme.outline.withOpacity(0.05)), ), child: Column( children: tiles, ), ), ], ); } Future _authenticate(BuildContext context, String correctPin) async { final controller = TextEditingController(); final pin = await showDialog( context: context, builder: (context) => AlertDialog( title: const Text('Enter PIN'), content: TextField( controller: controller, keyboardType: TextInputType.number, obscureText: true, maxLength: 4, textAlign: TextAlign.center, style: const TextStyle(fontSize: 24, letterSpacing: 8), decoration: const InputDecoration(hintText: '....'), autofocus: true, ), actions: [ TextButton(onPressed: () => Navigator.pop(context), child: const Text('Cancel')), ElevatedButton( onPressed: () => Navigator.pop(context, controller.text), child: const Text('Unlock'), ), ], ), ); return pin == correctPin; } void _showFavoritesDialog(BuildContext context, WidgetRef ref) async { final userProfile = ref.read(userProfileProvider); if (userProfile == null) return; if (userProfile.isBioProtected && userProfile.privacyPin != null) { final granted = await _authenticate(context, userProfile.privacyPin!); if (!granted) { if (context.mounted) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Incorrect PIN'))); } return; } } final controller = TextEditingController( text: userProfile.favoriteFoods?.join(', ') ?? '', ); if (!context.mounted) return; showDialog( context: context, builder: (context) => AlertDialog( title: Text('My Favorites', style: GoogleFonts.outfit(fontWeight: FontWeight.bold)), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'List your favorite comfort foods, snacks, or flowers so your husband knows what to get you!', style: GoogleFonts.outfit(fontSize: 13, color: AppColors.warmGray), ), const SizedBox(height: 16), TextField( controller: controller, maxLines: 3, decoration: const InputDecoration( hintText: 'e.g., Dark Chocolate, Sushi, Sunflowers...', border: OutlineInputBorder(), ), ), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Cancel'), ), ElevatedButton( onPressed: () { final favorites = controller.text .split(',') .map((e) => e.trim()) .where((e) => e.isNotEmpty) .toList(); final updatedProfile = userProfile.copyWith(favoriteFoods: favorites); ref.read(userProfileProvider.notifier).updateProfile(updatedProfile); Navigator.pop(context); }, child: const Text('Save'), ), ], ), ); } void _showShareDialog(BuildContext context, WidgetRef ref) { // Generate a simple pairing code (in a real app, this would be stored/validated) final userProfile = ref.read(userProfileProvider); final pairingCode = userProfile?.id?.substring(0, 6).toUpperCase() ?? 'ABC123'; showDialog( context: context, builder: (context) => AlertDialog( title: Row( children: [ Icon(Icons.share_outlined, color: Theme.of(context).colorScheme.primary), const SizedBox(width: 8), const Text('Share with Husband'), ], ), content: Column( mainAxisSize: MainAxisSize.min, children: [ Text( 'Share this code with your husband so he can connect to your cycle data:', style: GoogleFonts.outfit(fontSize: 14, color: AppColors.warmGray), ), const SizedBox(height: 24), Container( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(12), border: Border.all(color: Theme.of(context).colorScheme.primary.withOpacity(0.3)), ), child: SelectableText( pairingCode, style: GoogleFonts.outfit( fontSize: 32, fontWeight: FontWeight.bold, letterSpacing: 4, color: Theme.of(context).colorScheme.primary, ), ), ), const SizedBox(height: 16), Text( 'He can enter this in his app under Settings > Connect with Wife.', style: GoogleFonts.outfit(fontSize: 12, color: AppColors.warmGray), textAlign: TextAlign.center, ), ], ), actions: [ ElevatedButton( onPressed: () => Navigator.pop(context), style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).colorScheme.primary, foregroundColor: Colors.white, ), child: const Text('Done'), ), ], ), ); } } Widget _buildWifeTipsSection(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Health Tips', style: Theme.of(context).textTheme.titleLarge?.copyWith( fontSize: 18, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 12), Card( elevation: 2, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildTipCard( context, title: 'Regular Check-ups', content: 'Schedule regular gynecological check-ups to monitor your reproductive health.', icon: Icons.medical_services, ), const SizedBox(height: 16), _buildTipCard( context, title: 'Healthy Lifestyle', content: 'Maintain a balanced diet, exercise regularly, and get adequate sleep.', icon: Icons.healing, ), const SizedBox(height: 16), _buildTipCard( context, title: 'Partner Communication', content: 'Discuss health concerns openly with your partner to ensure mutual understanding.', icon: Icons.chat, ), ], ), ), ), ], ); } Widget _buildTipCard( BuildContext context, { required String title, required String content, required IconData icon, }) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Theme.of(context).colorScheme.primary.withOpacity(0.1), borderRadius: BorderRadius.circular(8), ), child: Icon( icon, color: Theme.of(context).colorScheme.primary, size: 20, ), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: GoogleFonts.outfit( fontWeight: FontWeight.w600, fontSize: 14, color: Theme.of(context).colorScheme.onSurface, ), ), const SizedBox(height: 4), Text( content, style: GoogleFonts.outfit( fontSize: 13, color: Theme.of(context).colorScheme.onSurfaceVariant, ), ), ], ), ), ], ); }