import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:firebase_core/firebase_core.dart'; import '../config/config_loader.dart'; import '../data/local/local_storage_service.dart'; import '../data/nostr/nostr_service.dart'; import '../data/sync/sync_engine.dart'; import '../data/firebase/firebase_service.dart'; import '../data/session/session_service.dart'; import '../data/immich/immich_service.dart'; import 'app_services.dart'; import 'service_locator.dart'; import 'logger.dart'; /// Initializes all application services. /// /// Handles the complete initialization sequence: /// 1. Load environment configuration /// 2. Initialize Firebase (if enabled) /// 3. Initialize local storage /// 4. Initialize Nostr service and sync engine /// 5. Initialize Immich service /// 6. Initialize Firebase service (if enabled) /// 7. Initialize session service /// 8. Register all services with ServiceLocator class AppInitializer { /// Initializes all application services. /// /// [environment] - The environment to use ('dev' or 'prod'). /// /// Returns an [AppServices] instance with all initialized services. /// /// Throws if initialization fails. static Future initialize({ String environment = 'dev', }) async { Logger.info('Starting application initialization...'); // Load .env file (optional - falls back to defaults if not found) try { await dotenv.load(fileName: '.env'); Logger.debug('.env file loaded successfully'); } catch (e) { Logger.warning('.env file not found, using default values: $e'); } // Load configuration based on environment final config = ConfigLoader.load(environment); Logger.setEnabled(config.enableLogging); Logger.info('Configuration loaded for environment: $environment'); // Initialize Firebase if enabled if (config.firebaseConfig.enabled) { try { await Firebase.initializeApp(); Logger.info('Firebase initialized successfully'); } catch (e) { Logger.error( 'Firebase initialization failed: $e', e, ); Logger.warning( 'Note: Firebase requires google-services.json (Android) and GoogleService-Info.plist (iOS)', ); } } // Initialize local storage service Logger.debug('Initializing local storage service...'); final storageService = LocalStorageService(); try { await storageService.initialize(); Logger.info('Local storage service initialized'); } catch (e) { Logger.error('Failed to initialize storage: $e', e); rethrow; } // Initialize Nostr service and sync engine Logger.debug('Initializing Nostr service...'); final nostrService = NostrService(); final nostrKeyPair = nostrService.generateKeyPair(); final syncEngine = SyncEngine( localStorage: storageService, nostrService: nostrService, nostrKeyPair: nostrKeyPair, ); Logger.info('Nostr service and sync engine initialized'); // Load relays from config for (final relayUrl in config.nostrRelays) { nostrService.addRelay(relayUrl); } Logger.debug('Loaded ${config.nostrRelays.length} relay(s) from config'); // Initialize Immich service Logger.debug('Initializing Immich service...'); final immichService = ImmichService( baseUrl: config.immichBaseUrl, apiKey: config.immichApiKey, localStorage: storageService, ); Logger.info('Immich service initialized'); // Initialize Firebase service if enabled FirebaseService? firebaseService; if (config.firebaseConfig.enabled) { try { Logger.debug('Initializing Firebase service...'); firebaseService = FirebaseService( config: config.firebaseConfig, localStorage: storageService, ); await firebaseService.initialize(); Logger.info('Firebase service initialized: ${firebaseService.isEnabled}'); } catch (e) { Logger.error('Firebase service initialization failed: $e', e); firebaseService = null; } } // Initialize SessionService with Firebase and Nostr integration Logger.debug('Initializing session service...'); final sessionService = SessionService( localStorage: storageService, syncEngine: syncEngine, firebaseService: firebaseService, nostrService: nostrService, ); Logger.info('Session service initialized'); // Create AppServices container final appServices = AppServices( localStorageService: storageService, nostrService: nostrService, syncEngine: syncEngine, firebaseService: firebaseService, sessionService: sessionService, immichService: immichService, ); // Register all services with ServiceLocator ServiceLocator.instance.registerServices( localStorageService: storageService, nostrService: nostrService, syncEngine: syncEngine, firebaseService: firebaseService, sessionService: sessionService, immichService: immichService, ); Logger.info('Application initialization completed successfully'); return appServices; } }