import 'dart:async'; import 'package:be_happy/core/failures.dart'; import 'package:be_happy/domain/entities/scooter_order.dart'; import 'package:be_happy/domain/usecase/get_profile_usecase.dart'; import 'package:collection/collection.dart'; import 'package:be_happy/domain/entities/payment_card.dart'; import 'package:be_happy/domain/usecase/book_scooter_usecase.dart'; import 'package:be_happy/domain/usecase/get_payment_cards_usecase.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../core/result.dart'; import '../../domain/entities/tariff.dart'; import '../../domain/usecase/get_available_tariffs_usecase.dart'; import '../event/tariff_sheet_event.dart'; import '../state/tariff_sheet_state.dart'; class TariffSheetBloc extends Bloc { final GetAvailableTariffsUsecase _getAvailableTariffsUsecase; final GetProfileUseCase _getProfileUseCase; final GetPaymentCardsUsecase _getPaymentCardsUsecase; final BookScooterUsecase _bookScooterUsecase; TariffSheetBloc( this._getAvailableTariffsUsecase, this._getProfileUseCase, this._getPaymentCardsUsecase, this._bookScooterUsecase, ) : super(TariffSheetState(status: TariffSheetStatus.initial)) { on(_onStarted); on(_onPaymentCardChanged); on(_onBookScooterPressed); on(_onSelectBalancePressed); on(_onInsuranceToggled); } Future _onStarted( TariffSheetStarted event, Emitter emit, ) async { emit(state.copyWith(status: TariffSheetStatus.loading)); try { final result = await _getAvailableTariffsUsecase(event.scooterId); final cards_result = await _getPaymentCardsUsecase(); if (result is Success> && cards_result is Success>) { emit( state.copyWith( status: TariffSheetStatus.success, tariffs: result.data ?? [], selectedCard: cards_result.data?.firstWhereOrNull( (element) => element.isMain, ), ), ); } else { emit( state.copyWith( status: TariffSheetStatus.failure, errorMessage: 'Failed to load tariffs', ), ); } } catch (e, stackTrace) { emit( state.copyWith( status: TariffSheetStatus.failure, errorMessage: "ERROR: ${e.toString()} \n $stackTrace", ), ); } } FutureOr _onPaymentCardChanged( PaymentCardChanged event, Emitter emit, ) { try { emit( state.copyWith( status: TariffSheetStatus.success, selectedCard: event.card, useBalance: false, ), ); } catch (e) { emit( state.copyWith( status: TariffSheetStatus.failure, errorMessage: 'Failed to change card', ), ); } } FutureOr _onBookScooterPressed ( BookScooterPressed event, Emitter emit, ) async { try { final result = await _bookScooterUsecase( scooterId: event.scooterId, planId: event.planId, cardId: event.cardId, subscriptionId: event.subscriptionId, isBalance: event.isBalance, isInsurance: event.isInsurance, ); switch (result) { case Success(): // TODO: Handle this case. throw UnimplementedError(); case Failure(): if (result is WrongZoneFailure) { emit( state.copyWith( status: TariffSheetStatus.failure, errorMessage: result.failure.message, ), ); } } } catch (e) { emit( state.copyWith( status: TariffSheetStatus.failure, errorMessage: 'Failed to book scooter', ), ); } } FutureOr _onSelectBalancePressed(SelectBalancePressed event, Emitter emit) async { final profile = await _getProfileUseCase(); emit(state.copyWith( useBalance: true, userBalance: profile.balance, selectedCard: null, )); } FutureOr _onInsuranceToggled(InsuranceToggled event, Emitter emit) async { emit(state.copyWith(isInsurance: event.isEnabled)); } }