import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:travel_mate/blocs/balance/balance_bloc.dart';
import 'package:travel_mate/blocs/expense/expense_bloc.dart';
import 'package:google_maps_flutter_android/google_maps_flutter_android.dart';
import 'package:google_maps_flutter_platform_interface/google_maps_flutter_platform_interface.dart';
import 'package:travel_mate/blocs/message/message_bloc.dart';
import 'package:travel_mate/blocs/activity/activity_bloc.dart';
import 'package:travel_mate/firebase_options.dart';
import 'package:travel_mate/services/balance_service.dart';
import 'package:travel_mate/services/error_service.dart';
import 'package:travel_mate/services/activity_places_service.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:travel_mate/services/expense_service.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:travel_mate/services/notification_service.dart';
import 'package:travel_mate/services/map_navigation_service.dart';
import 'package:travel_mate/services/analytics_service.dart';
import 'blocs/auth/auth_bloc.dart';
import 'blocs/auth/auth_event.dart';
import 'blocs/theme/theme_bloc.dart';
import 'blocs/theme/theme_event.dart';
import 'blocs/theme/theme_state.dart';
import 'blocs/group/group_bloc.dart';
import 'blocs/user/user_bloc.dart';
import 'blocs/trip/trip_bloc.dart';
import 'blocs/account/account_bloc.dart';
import 'repositories/auth_repository.dart';
import 'repositories/trip_repository.dart';
import 'repositories/user_repository.dart';
import 'repositories/group_repository.dart';
import 'repositories/message_repository.dart';
import 'repositories/account_repository.dart';
import 'repositories/expense_repository.dart';
import 'repositories/balance_repository.dart';
import 'repositories/activity_repository.dart';
import 'pages/login.dart';
import 'pages/home.dart';
import 'pages/signup.dart';
import 'pages/resetpswd.dart';

import 'package:intl/date_symbol_data_local.dart';

/// Entry point of the Travel Mate application.
///
/// This function initializes Flutter widgets, loads environment variables,
/// initializes Firebase, and starts the application.
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown,
  ]);
  await dotenv.load(fileName: ".env");
  await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
  await initializeDateFormatting('fr_FR', null);

  // Set the background messaging handler early on, as a named top-level function
  FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);

  await NotificationService().initialize();

  // Requirements for Google Maps on Android (Hybrid Composition)
  final GoogleMapsFlutterPlatform mapsImplementation =
      GoogleMapsFlutterPlatform.instance;
  if (mapsImplementation is GoogleMapsFlutterAndroid) {
    mapsImplementation.useAndroidViewSurface = true;
  }

  runApp(const MyApp());
}

/// The root widget of the Travel Mate application.
///
/// This widget sets up the BLoC providers, repositories, and MaterialApp
/// configuration. It manages the application's theme, routing, and global state.
class MyApp extends StatelessWidget {
  /// Creates the main application widget.
  const MyApp({super.key});

  /// Builds the widget tree for the application.
  ///
  /// Sets up repository providers for dependency injection, BLoC providers
  /// for state management, and configures the MaterialApp with themes and routing.
  @override
  Widget build(BuildContext context) {
    return MultiRepositoryProvider(
      providers: [
        // Authentication repository for handling user authentication
        RepositoryProvider<AuthRepository>(
          create: (context) => AuthRepository(),
        ),
        // User repository for managing user data
        RepositoryProvider<UserRepository>(
          create: (context) => UserRepository(),
        ),
        // Trip repository for managing travel trips
        RepositoryProvider<TripRepository>(
          create: (context) => TripRepository(),
        ),
        // Group repository for managing travel groups
        RepositoryProvider<GroupRepository>(
          create: (context) => GroupRepository(),
        ),
        // Message repository for handling in-app messaging
        RepositoryProvider<MessageRepository>(
          create: (context) => MessageRepository(),
        ),
        // Account repository for managing user account settings
        RepositoryProvider<AccountRepository>(
          create: (context) => AccountRepository(),
        ),
        // Expense repository for managing trip expenses
        RepositoryProvider<ExpenseRepository>(
          create: (context) => ExpenseRepository(),
        ),
        // Expense service for business logic related to expenses
        RepositoryProvider<ExpenseService>(
          create: (context) => ExpenseService(
            expenseRepository: context.read<ExpenseRepository>(),
          ),
        ),
        // Balance repository for calculating expense balances
        RepositoryProvider<BalanceRepository>(
          create: (context) => BalanceRepository(
            expenseRepository: context.read<ExpenseRepository>(),
          ),
        ),
        // Activity repository for managing trip activities
        RepositoryProvider<ActivityRepository>(
          create: (context) => ActivityRepository(),
        ),
        // Activity places service for Google Places API integration
        RepositoryProvider<ActivityPlacesService>(
          create: (context) => ActivityPlacesService(),
        ),
        // Balance service for business logic related to balances
        RepositoryProvider<BalanceService>(
          create: (context) => BalanceService(
            balanceRepository: context.read<BalanceRepository>(),
            expenseRepository: context.read<ExpenseRepository>(),
          ),
        ),
        // Map navigation service
        RepositoryProvider<MapNavigationService>(
          create: (context) => MapNavigationService(),
        ),
        // Analysis service
        RepositoryProvider<AnalyticsService>(
          create: (context) => AnalyticsService(),
        ),
      ],
      child: MultiBlocProvider(
        providers: [
          // Theme BLoC for managing app theme preferences
          BlocProvider<ThemeBloc>(
            create: (context) => ThemeBloc()..add(ThemeLoadRequested()),
          ),
          // Authentication BLoC for managing user authentication state
          BlocProvider<AuthBloc>(
            create: (context) =>
                AuthBloc(authRepository: context.read<AuthRepository>())
                  ..add(AuthCheckRequested()),
          ),
          // Group BLoC for managing travel groups
          BlocProvider(
            create: (context) => GroupBloc(context.read<GroupRepository>()),
          ),
          // Trip BLoC for managing travel trips
          BlocProvider(
            create: (context) => TripBloc(context.read<TripRepository>()),
          ),
          // User BLoC for managing user data
          BlocProvider(create: (context) => UserBloc()),
          // Message BLoC for managing in-app messaging
          BlocProvider(create: (context) => MessageBloc()),
          // Account BLoC for managing user account settings
          BlocProvider(
            create: (context) => AccountBloc(context.read<AccountRepository>()),
          ),

          // Expense BLoC for managing trip expenses
          BlocProvider<ExpenseBloc>(
            create: (context) => ExpenseBloc(
              expenseRepository: context.read<ExpenseRepository>(),
              expenseService: context.read<ExpenseService>(),
            ),
          ),
          // Balance BLoC for managing expense balances and calculations
          BlocProvider<BalanceBloc>(
            create: (context) => BalanceBloc(
              balanceRepository: context.read<BalanceRepository>(),
              balanceService: context.read<BalanceService>(),
              expenseRepository: context.read<ExpenseRepository>(),
            ),
          ),
          // Activity BLoC for managing trip activities
          BlocProvider<ActivityBloc>(
            create: (context) => ActivityBloc(
              repository: context.read<ActivityRepository>(),
              placesService: context.read<ActivityPlacesService>(),
              errorService: ErrorService(),
            ),
          ),
        ],
        child: BlocBuilder<ThemeBloc, ThemeState>(
          builder: (context, themeState) {
            return MaterialApp(
              title: 'Travel Mate',
              navigatorKey: ErrorService.navigatorKey,
              themeMode: themeState.themeMode,
              navigatorObservers: [
                context.read<AnalyticsService>().getAnalyticsObserver(),
              ],
              // Light theme configuration
              theme: ThemeData(
                colorScheme: ColorScheme.fromSeed(
                  seedColor: const Color.fromARGB(255, 180, 180, 180),
                  brightness: Brightness.light,
                ),
                useMaterial3: true,
                appBarTheme: const AppBarTheme(
                  backgroundColor: Colors.white,
                  foregroundColor: Colors.black,
                  elevation: 0,
                  surfaceTintColor: Colors.transparent,
                ),
              ),
              // Dark theme configuration
              darkTheme: ThemeData(
                colorScheme: ColorScheme.fromSeed(
                  seedColor: const Color.fromARGB(255, 43, 43, 43),
                  brightness: Brightness.dark,
                ),
                useMaterial3: true,
                appBarTheme: const AppBarTheme(
                  backgroundColor: Colors.black,
                  foregroundColor: Colors.white,
                  elevation: 0,
                  surfaceTintColor: Colors.transparent,
                ),
              ),
              // Default page when app starts
              home: const LoginPage(),
              // Named routes for navigation
              routes: {
                '/login': (context) => const LoginPage(),
                '/signup': (context) => const SignUpPage(),
                '/home': (context) => const HomePage(),
                '/forgot': (context) => const ForgotPasswordPage(),
              },
              debugShowCheckedModeBanner: false,
            );
          },
        ),
      ),
    );
  }
}
