import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
import 'package:krow_core/core.dart';
import 'package:krow_data_connect/krow_data_connect.dart';
import 'package:staff_authentication/src/data/repositories_impl/auth_repository_impl.dart';
import 'package:staff_authentication/src/domain/repositories/auth_repository_interface.dart';
import 'package:staff_authentication/src/domain/usecases/sign_in_with_phone_usecase.dart';
import 'package:staff_authentication/src/domain/usecases/verify_otp_usecase.dart';
import 'package:staff_authentication/src/domain/repositories/profile_setup_repository.dart';
import 'package:staff_authentication/src/data/repositories_impl/profile_setup_repository_impl.dart';
import 'package:staff_authentication/src/domain/usecases/submit_profile_setup_usecase.dart';
import 'package:staff_authentication/src/domain/repositories/place_repository.dart';
import 'package:staff_authentication/src/data/repositories_impl/place_repository_impl.dart';
import 'package:staff_authentication/src/domain/usecases/search_cities_usecase.dart';
import 'package:staff_authentication/src/presentation/blocs/auth_bloc.dart';
import 'package:staff_authentication/src/presentation/blocs/profile_setup/profile_setup_bloc.dart';
import 'package:staff_authentication/src/presentation/pages/intro_page.dart';
import 'package:staff_authentication/src/presentation/pages/get_started_page.dart';
import 'package:staff_authentication/src/presentation/pages/phone_verification_page.dart';
import 'package:staff_authentication/src/presentation/pages/profile_setup_page.dart';
import 'package:staff_authentication/src/domain/ui_entities/auth_mode.dart';

///  A [Module] for the staff authentication feature.
class StaffAuthenticationModule extends Module {
  @override
  List<Module> get imports => <Module>[DataConnectModule()];

  @override
  void binds(Injector i) {
    // Repositories
    i.addLazySingleton<AuthRepositoryInterface>(AuthRepositoryImpl.new);
    i.addLazySingleton<ProfileSetupRepository>(ProfileSetupRepositoryImpl.new);
    i.addLazySingleton<PlaceRepository>(PlaceRepositoryImpl.new);

    // UseCases
    i.addLazySingleton(SignInWithPhoneUseCase.new);
    i.addLazySingleton(VerifyOtpUseCase.new);
    i.addLazySingleton(SubmitProfileSetup.new);
    i.addLazySingleton(SearchCitiesUseCase.new);

    // BLoCs
    i.addLazySingleton<AuthBloc>(
      () => AuthBloc(
        signInUseCase: i.get<SignInWithPhoneUseCase>(),
        verifyOtpUseCase: i.get<VerifyOtpUseCase>(),
      ),
    );
    i.add<ProfileSetupBloc>(
      () => ProfileSetupBloc(
        submitProfileSetup: i.get<SubmitProfileSetup>(),
        searchCities: i.get<SearchCitiesUseCase>(),
      ),
    );
  }

  @override
  void routes(RouteManager r) {
    r.child(StaffPaths.root, child: (_) => const IntroPage());
    r.child(StaffPaths.getStarted, child: (_) => const GetStartedPage());
    r.child(
      StaffPaths.phoneVerification,
      child: (BuildContext context) {
        final Map<String, dynamic>? data = r.args.data;
        final String? modeName = data?['mode'];
        final AuthMode mode = AuthMode.values.firstWhere(
          (AuthMode e) => e.name == modeName,
          orElse: () => AuthMode.login,
        );
        return PhoneVerificationPage(mode: mode);
      },
    );
    r.child(StaffPaths.profileSetup, child: (_) => const ProfileSetupPage());
  }
}
