import 'package:get_it/get_it.dart';
import 'package:supabase_flutter/supabase_flutter.dart';
import 'package:tugas_akhir_supabase/core/constants/app_constants.dart';
import 'package:tugas_akhir_supabase/data/repositories/crop_schedule_repository_impl.dart';
import 'package:tugas_akhir_supabase/data/repositories/field_repository_impl.dart';
import 'package:tugas_akhir_supabase/domain/repositories/crop_schedule_repository.dart';
import 'package:tugas_akhir_supabase/domain/repositories/field_repository.dart';
import 'package:tugas_akhir_supabase/domain/usecases/field_usecases.dart';
import 'package:tugas_akhir_supabase/domain/usecases/get_schedules.dart';
import 'package:tugas_akhir_supabase/presentation/blocs/crop_schedule/crop_schedule_bloc.dart';
import 'package:tugas_akhir_supabase/presentation/blocs/field/field_bloc.dart';
import 'package:tugas_akhir_supabase/services/auth_services.dart';
import 'package:tugas_akhir_supabase/services/user_presence_service.dart';
import 'package:flutter/foundation.dart';

final sl = GetIt.instance;

Future<void> initServiceLocator() async {
  // External dependencies
  final supabase = Supabase.instance.client;
  sl.registerLazySingleton<SupabaseClient>(() => supabase);

  // Core

  // Services
  sl.registerLazySingleton<AuthServices>(() => AuthServices());

  // Register UserPresenceService only if we have an authenticated user
  try {
    final currentUser = supabase.auth.currentUser;
    if (currentUser != null) {
      if (!sl.isRegistered<UserPresenceService>()) {
        debugPrint(
          'Registering UserPresenceService for user ${currentUser.id}',
        );
        sl.registerLazySingleton<UserPresenceService>(
          () => UserPresenceService(),
        );
        // Initialize the service
        await sl<UserPresenceService>().initialize();
      }
    } else {
      debugPrint(
        'No authenticated user, skipping UserPresenceService registration',
      );
    }
  } catch (e) {
    debugPrint('Error registering UserPresenceService: $e');
  }

  // Data sources

  // Repositories
  sl.registerLazySingleton<CropScheduleRepository>(
    () => CropScheduleRepositoryImpl(supabaseClient: sl()),
  );

  sl.registerLazySingleton<FieldRepository>(
    () => FieldRepositoryImpl(supabaseClient: sl()),
  );

  // Use cases - Crop Schedule
  sl.registerLazySingleton(() => GetSchedules(sl()));
  sl.registerLazySingleton(() => GetActiveSchedule(sl()));
  sl.registerLazySingleton(() => CreateSchedule(sl()));
  sl.registerLazySingleton(() => UpdateSchedule(sl()));
  sl.registerLazySingleton(() => DeleteSchedule(sl()));

  // Use cases - Field
  sl.registerLazySingleton(() => GetFields(sl()));
  sl.registerLazySingleton(() => CreateField(sl()));
  sl.registerLazySingleton(() => UpdateField(sl()));
  sl.registerLazySingleton(() => DeleteField(sl()));

  // Blocs
  sl.registerFactory(
    () => CropScheduleBloc(
      getSchedules: sl(),
      getActiveSchedule: sl(),
      createSchedule: sl(),
      updateSchedule: sl(),
      deleteSchedule: sl(),
    ),
  );

  sl.registerFactory(
    () => FieldBloc(
      getFields: sl(),
      createField: sl(),
      updateField: sl(),
      deleteField: sl(),
    ),
  );
}
