import 'dart:async'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:url_launcher/url_launcher.dart'; import '../../core/result.dart'; import '../../domain/entities/payment_card.dart'; import '../../domain/usecase/add_payment_card_usecase.dart'; import '../../domain/usecase/get_payment_cards_usecase.dart'; import '../../domain/usecase/get_profile_usecase.dart'; import '../../domain/usecase/set_main_payment_card_usecase.dart'; import '../event/payment_method_sheet_event.dart'; import '../state/payment_method_sheet_state.dart'; class PaymentMethodSheetBloc extends Bloc { final GetPaymentCardsUsecase _getPaymentCardsUsecase; final GetProfileUseCase _getProfileUseCase; final SetMainPaymentCardUsecase _setMainPaymentCardUsecase; final AddPaymentCardUsecase _addPaymentCardUsecase; PaymentMethodSheetBloc(this._getPaymentCardsUsecase, this._setMainPaymentCardUsecase, this._getProfileUseCase, this._addPaymentCardUsecase) : super( PaymentMethodSheetState(status: PaymentMethodSheetStatus.initial)) { on(_onStarted); on(_onAddCardButtonPressed); } Future _onStarted(PaymentMethodSheetStarted event, Emitter emit,) async { emit(state.copyWith(status: PaymentMethodSheetStatus.loading)); try { final result = await _getPaymentCardsUsecase(); final profile = await _getProfileUseCase(); if (result is Success>) { emit(state.copyWith( status: PaymentMethodSheetStatus.success, balance: profile.balance, cards: result.data ?? [], )); } else { emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: 'Failed to load payment cards', )); } } catch (e) { emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: e.toString(), )); } } Future _onSelectCard(SelectPaymentCardRequested event, Emitter emit,) async { // Включаем локальный лоадер на шторке, либо просто ждем ответа emit(state.copyWith(status: PaymentMethodSheetStatus.loading)); final result = await _setMainPaymentCardUsecase(event.card.id); if (result is Success) { final cardsResult = await _getPaymentCardsUsecase(); if (cardsResult is Success>) { emit(state.copyWith( status: PaymentMethodSheetStatus.success, cards: cardsResult.data ?? [], )); } else { emit(state.copyWith(status: PaymentMethodSheetStatus.failure, errorMessage: 'Ошибка обновления списка карт')); } } else { emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: 'Не удалось установить карту основной', )); } } // Выносим загрузку в отдельный метод для переиспользования Future _loadCards(Emitter emit) async { try { final result = await _getPaymentCardsUsecase(); if (result is Success>) { emit(state.copyWith( status: PaymentMethodSheetStatus.success, cards: result.data ?? [], )); } else { emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: 'Failed to load payment cards', )); } } catch (e) { emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: e.toString(), )); } } FutureOr _onAddCardButtonPressed(AddCardButtonPressed event, Emitter emit) async { try { final result = await _addPaymentCardUsecase(); if (result is Success>) { final formUrlString = result.data?['formUrl'] as String?; if (formUrlString != null && formUrlString.isNotEmpty) { final url = Uri.parse(formUrlString); if (await canLaunchUrl(url) ) { launchUrl( url, mode: LaunchMode.externalApplication, ); emit(state.copyWith(status: PaymentMethodSheetStatus.success)); } else { emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: 'Не удалось открыть ссылку для оплаты', )); } } else { emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: 'Ссылка для привязки карты не получена от сервера', )); } } else if (result is Failure) { String errorMessage = 'Ошибка при добавлении карты'; emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: errorMessage, )); } } catch (e) { emit(state.copyWith( status: PaymentMethodSheetStatus.failure, errorMessage: e.toString(), )); } } }