import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:provider/provider.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:async'; import 'dart:math'; import 'package:hive/hive.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; // <-- Importação necessária import 'firebase_options.dart'; import 'package:kzeduca_app/services/i18n_service.dart'; import 'package:kzeduca_app/services/firebase_service.dart'; import 'services/toast_service.dart'; import 'package:kzeduca_app/screens/auth_screen.dart'; import 'package:kzeduca_app/screens/dashboard_screen.dart'; import 'package:kzeduca_app/screens/add_transaction_screen.dart'; import 'package:kzeduca_app/screens/statistics_screen.dart'; import 'package:kzeduca_app/screens/budget_screen.dart'; import 'package:kzeduca_app/screens/create_budget_screen.dart'; import 'package:kzeduca_app/screens/savings_calculator_screen.dart'; import 'package:kzeduca_app/screens/settings_screen.dart'; import 'package:kzeduca_app/screens/financial_agent_screen.dart'; import 'package:kzeduca_app/services/user_state_service.dart'; import 'package:kzeduca_app/models/transaction.dart' as app; import 'package:kzeduca_app/models/budget.dart'; import 'package:kzeduca_app/services/hive_service.dart'; import 'package:kzeduca_app/services/transaction_list_notifier.dart'; // Importação necessária para o GameStateProvider import 'package:kzeduca_app/providers/game_state_provider.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); await Hive.initFlutter(); Hive.registerAdapter(app.TransactionTypeAdapter()); Hive.registerAdapter(app.TransactionCategoryAdapter()); Hive.registerAdapter(app.TransactionAdapter()); Hive.registerAdapter(BudgetPeriodAdapter()); Hive.registerAdapter(BudgetAdapter()); await Hive.openBox('transactions'); await Hive.openBox('budgets'); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); // Ativa o cache offline do Firestore FirebaseFirestore.instance.settings = const Settings( persistenceEnabled: true, ); runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => I18nService()), ChangeNotifierProvider(create: (_) => UserStateService()), ChangeNotifierProvider(create: (_) => TransactionListNotifier()), ChangeNotifierProvider(create: (_) => GameStateProvider()), // <-- AGORA ADICIONADO! Provider( create: (context) => FirebaseService( Provider.of(context, listen: false), ), ), Provider(create: (_) => HiveService()), ], child: const KzEducaApp(), ), ); } class KzEducaApp extends StatefulWidget { const KzEducaApp({super.key}); @override State createState() => _KzEducaAppState(); } class _KzEducaAppState extends State { late final Future _appInitializationFuture; @override void initState() { super.initState(); // Atraso a inicialização para garantir que o SplashScreen seja visível _appInitializationFuture = _initializeApp(); } Future _initializeApp() async { // Tarefas de inicialização do aplicativo final initializationTasks = Future.microtask(() async { final i18nService = Provider.of(context, listen: false); await i18nService.setLocale(i18nService.locale); await Provider.of(context, listen: false).recalculateBalanceFromHive(); await Provider.of(context, listen: false).loadTransactions(); }); // Atraso mínimo para garantir que o splash screen seja exibido const minimumSplashDuration = Duration(seconds: 4); final splashFuture = Future.delayed(minimumSplashDuration); // Aguarda a conclusão de ambas as tarefas await Future.wait([initializationTasks, splashFuture]); } void _changeCurrency(String newCurrencySymbol) {} @override Widget build(BuildContext context) { final i18n = Provider.of(context); return MaterialApp( debugShowCheckedModeBanner: false, title: i18n.t('app_name'), theme: ThemeData( primarySwatch: Colors.blue, fontFamily: 'Inter', visualDensity: VisualDensity.adaptivePlatformDensity, inputDecorationTheme: InputDecorationTheme( filled: true, fillColor: Colors.white.withOpacity(0.8), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12.0), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12.0), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12.0), borderSide: const BorderSide(color: Colors.blueAccent, width: 2.0), ), contentPadding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 20.0), ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), ), textStyle: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600), elevation: 5, shadowColor: Colors.black.withOpacity(0.2), ), ), ), locale: i18n.locale, localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: i18n.supportedLocales, home: FutureBuilder( future: _appInitializationFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const SplashScreen(); } if (snapshot.hasError) { return Center(child: Text('Erro ao inicializar: ${snapshot.error}')); } return StreamBuilder( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, authSnapshot) { // A verificação de loading na tela de auth é desnecessária agora, // já que o FutureBuilder do SplashScreen já tratou do estado de espera inicial. if (authSnapshot.hasData) { final userStateService = Provider.of(context, listen: false); userStateService.fetchUserData(authSnapshot.data!.uid); return const DashboardScreen(); } return const AuthScreen(); }, ); }, ), routes: { '/add_transaction': (context) => const AddTransactionScreen(), '/budget': (context) => const BudgetScreen(), '/statistics': (context) => const StatisticsScreen(), '/savings_calculator': (context) => const SavingsCalculatorScreen(), '/create_budget': (context) => const CreateBudgetScreen(), '/settings': (context) => SettingsScreen( onLocaleChanged: (locale) {}, onCurrencyChanged: _changeCurrency, ), '/financial_agent': (context) => const MainMenuScreen(), }, ); } } class SplashScreen extends StatefulWidget { const SplashScreen({super.key}); @override State createState() => _SplashScreenState(); } class _SplashScreenState extends State with SingleTickerProviderStateMixin { late AnimationController _controller; late Animation _logoOpacity; @override void initState() { super.initState(); _controller = AnimationController( vsync: this, duration: const Duration(seconds: 4), )..forward(); _logoOpacity = Tween(begin: 0.0, end: 1.0).animate( CurvedAnimation( parent: _controller, curve: const Interval(0.0, 0.6, curve: Curves.easeIn), ), ); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFF1E1C3A), body: Center( child: FadeTransition( opacity: _logoOpacity, child: Image.asset( 'assets/images/kzeduca_logo.png', // Verifique se o caminho da imagem está correto width: 200, height: 200, ), ), ), ); } }