import 'dart:async'; import 'package:flutter/material.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'main.dart'; // Import ChristianPeriodTrackerApp import 'models/cycle_entry.dart'; import 'models/teaching_plan.dart'; import 'models/prayer_request.dart'; import 'models/scripture.dart'; import 'models/user_profile.dart'; import 'screens/splash_screen.dart'; import 'services/notification_service.dart'; class AppStartupWidget extends StatefulWidget { const AppStartupWidget({super.key}); @override State createState() => _AppStartupWidgetState(); } class _AppStartupWidgetState extends State { bool _isInitialized = false; String _status = 'Initializing...'; bool _showSkipButton = false; final Duration _minSplashDuration = const Duration(milliseconds: 2000); @override void initState() { super.initState(); _initializeApp(); // Show skip button if loading takes too long (e.g., 5 seconds) Future.delayed(const Duration(seconds: 5), () { if (mounted && !_isInitialized) { setState(() => _showSkipButton = true); } }); } Future _initializeApp() async { final stopwatch = Stopwatch()..start(); try { setState(() => _status = 'Loading user profile...'); // Add timeout to prevent indefinite hanging await Hive.openBox('user_profile_v2') .timeout(const Duration(seconds: 5)); setState(() => _status = 'Loading cycle data...'); await Hive.openBox('cycle_entries_v2') .timeout(const Duration(seconds: 5)); setState(() => _status = 'Loading shared data...'); await Hive.openBox('teaching_plans_v2') .timeout(const Duration(seconds: 5)); await Hive.openBox('prayer_requests_v2') .timeout(const Duration(seconds: 5)); setState(() => _status = 'Loading scriptures...'); // Wrap scripture loading in a try-catch specifically to allow app to start even if assets fail try { await ScriptureDatabase() .loadScriptures() .timeout(const Duration(seconds: 5)); } catch (e) { debugPrint('Scripture loading failed (non-critical): $e'); setState(() => _status = 'Scripture loading skipped...'); } setState(() => _status = 'Setting up notifications...'); try { await NotificationService() .initialize() .timeout(const Duration(seconds: 3)); } catch (e) { debugPrint('Notification init failed: $e'); } } catch (e, stack) { debugPrint('Initialization error: $e'); debugPrint(stack.toString()); setState(() => _status = 'Error: $e'); // On critical error, allow user to proceed manually via skip button setState(() => _showSkipButton = true); return; } final elapsed = stopwatch.elapsed; if (elapsed < _minSplashDuration) { await Future.delayed(_minSplashDuration - elapsed); } if (mounted) { setState(() { _isInitialized = true; }); } } void _skipInitialization() { setState(() => _isInitialized = true); } @override Widget build(BuildContext context) { if (!_isInitialized) { return MaterialApp( home: Scaffold( body: Stack( children: [ const SplashScreen(isStartup: true), // Status Message (High Visibility) Positioned( bottom: 80, left: 20, right: 20, child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white.withValues(alpha: 0.9), borderRadius: BorderRadius.circular(8), ), child: Text( _status, textAlign: TextAlign.center, style: const TextStyle( color: Colors.black87, fontSize: 14, fontWeight: FontWeight.bold, decoration: TextDecoration.none, fontFamily: 'SansSerif'), ), ), ), // Skip Button if (_showSkipButton) Positioned( bottom: 30, left: 0, right: 0, child: Center( child: ElevatedButton( onPressed: _skipInitialization, style: ElevatedButton.styleFrom( backgroundColor: Colors.redAccent, foregroundColor: Colors.white, ), child: const Text('Skip Loading (Force Start)'), ), ), ), ], ), ), debugShowCheckedModeBanner: false, ); } return const ChristianPeriodTrackerApp(); } }