import 'dart:developer'; import 'package:flutter/widgets.dart'; import 'package:test_sa/core/di/service_locator.dart'; import 'package:test_sa/modules/cx_module/chat/services/call_manager.dart'; /// App lifecycle observer to handle pending calls when app resumes class AppLifecycleObserver with WidgetsBindingObserver { static final AppLifecycleObserver _instance = AppLifecycleObserver._internal(); factory AppLifecycleObserver() => _instance; AppLifecycleObserver._internal(); bool _isInitialized = false; bool _hasCheckedPendingCall = false; /// Initialize the lifecycle observer void initialize() { if (_isInitialized) { log('⚠️ [LIFECYCLE] Already initialized', name: 'AppLifecycleObserver'); return; } log('πŸ”§ [LIFECYCLE] Initializing app lifecycle observer', name: 'AppLifecycleObserver'); WidgetsBinding.instance.addObserver(this); _isInitialized = true; log('βœ… [LIFECYCLE] Observer initialized', name: 'AppLifecycleObserver'); // Check for pending calls immediately on app start _checkPendingCallsOnStart(); } /// Dispose the observer void dispose() { if (_isInitialized) { log('🧹 [LIFECYCLE] Disposing lifecycle observer', name: 'AppLifecycleObserver'); WidgetsBinding.instance.removeObserver(this); _isInitialized = false; } } @override void didChangeAppLifecycleState(AppLifecycleState state) { log('═══════════════════════════════════════════', name: 'AppLifecycleObserver'); log('πŸ”„ [LIFECYCLE] App state changed: ${state.name}', name: 'AppLifecycleObserver'); switch (state) { case AppLifecycleState.resumed: log('βœ… [LIFECYCLE] App resumed - checking for pending calls', name: 'AppLifecycleObserver'); _onAppResumed(); break; case AppLifecycleState.inactive: log('⏸️ [LIFECYCLE] App inactive', name: 'AppLifecycleObserver'); break; case AppLifecycleState.paused: log('⏸️ [LIFECYCLE] App paused', name: 'AppLifecycleObserver'); break; case AppLifecycleState.detached: log('πŸ”΄ [LIFECYCLE] App detached', name: 'AppLifecycleObserver'); break; case AppLifecycleState.hidden: log('πŸ”΄ [LIFECYCLE] App hidden', name: 'AppLifecycleObserver'); break; } log('═══════════════════════════════════════════', name: 'AppLifecycleObserver'); } /// Check for pending calls when app starts Future _checkPendingCallsOnStart() async { try { // Wait a bit for app to fully initialize await Future.delayed(const Duration(milliseconds: 500)); log('═══════════════════════════════════════════', name: 'AppLifecycleObserver'); log('πŸ” [LIFECYCLE] Checking for pending calls on app start...', name: 'AppLifecycleObserver'); if (getIt.isRegistered()) { final callManager = getIt(); await callManager.checkForPendingCalls(); _hasCheckedPendingCall = true; log('βœ… [LIFECYCLE] Pending call check complete', name: 'AppLifecycleObserver'); } else { log('⚠️ [LIFECYCLE] CallManager not registered yet', name: 'AppLifecycleObserver'); } log('═══════════════════════════════════════════', name: 'AppLifecycleObserver'); } catch (e, stackTrace) { log('❌ [LIFECYCLE] Error checking pending calls on start: $e\nStack: $stackTrace', name: 'AppLifecycleObserver'); } } /// Handle app resumed state Future _onAppResumed() async { try { // Check for pending calls if we haven't already if (!_hasCheckedPendingCall) { log('πŸ” [LIFECYCLE] First resume - checking for pending calls', name: 'AppLifecycleObserver'); if (getIt.isRegistered()) { final callManager = getIt(); await callManager.checkForPendingCalls(); _hasCheckedPendingCall = true; } } // Handle pending navigation (if call was accepted while app was launching) if (getIt.isRegistered()) { final callManager = getIt(); await callManager.handlePendingNavigation(); } } catch (e, stackTrace) { log('❌ [LIFECYCLE] Error handling app resumed: $e\nStack: $stackTrace', name: 'AppLifecycleObserver'); } } /// Reset state (for testing) void reset() { _hasCheckedPendingCall = false; log('πŸ”„ [LIFECYCLE] State reset', name: 'AppLifecycleObserver'); } }