import 'package:flutter_bloc/flutter_bloc.dart'; import '../../../../core/payment/payment_gateway.dart'; import '../../../../core/resources/data_state.dart'; import '../../../../core/usecase/use_case.dart'; import '../../domain/use_cases/ad_reward_usecase.dart'; import '../../domain/use_cases/buy_card_usecase.dart'; import '../../domain/use_cases/get_shop_usecase.dart'; import '../../domain/use_cases/purchase_usecase.dart'; import '../../domain/use_cases/select_card_usecase.dart'; import 'shop_event.dart'; import 'shop_state.dart'; import 'shop_status.dart'; class ShopBloc extends Bloc { final GetShopUseCase getShopUseCase; final BuyCardUseCase buyCardUseCase; final SelectCardUseCase selectCardUseCase; final PurchaseUseCase purchaseUseCase; final AdRewardUseCase adRewardUseCase; final PaymentGateway gateway; ShopBloc( this.getShopUseCase, this.buyCardUseCase, this.selectCardUseCase, this.purchaseUseCase, this.adRewardUseCase, this.gateway, ) : super(ShopBlocState.initial()) { on((event, emit) => _load(emit)); on((event, emit) => _action(emit, () => buyCardUseCase(event.cardId))); on((event, emit) => _action(emit, () => selectCardUseCase(event.cardId))); on((event, emit) => _action(emit, () => _purchase(event))); on((event, emit) => _action( emit, () async { final res = await adRewardUseCase( 'dev-ad-${DateTime.now().millisecondsSinceEpoch}'); if (res is DataSuccess) { return const DataSuccess('سکه رایگان دریافت شد'); } return DataError(res.error!); }, )); } /// جریانِ خرید: ابتدا پرداختِ فروشگاهی (native) اجرا می‌شود، سپس مدرکِ خرید /// (token/purchaseData/signature) برای اعتبارسنجی به بک‌اند فرستاده می‌شود و /// در پایان، خرید در فروشگاه consume می‌شود. Future> _purchase(PurchaseEvent event) async { // برای پرداختِ native به SKUِ فروشگاه نیاز است؛ اگر تنظیم نشده باشد از // شناسه‌ی کاتالوگ استفاده می‌کنیم (حالتِ توسعه/تک‌فروشگاهی). final sku = event.sku.isNotEmpty ? event.sku : event.productId; final PurchaseResult result; try { result = await gateway.purchase(sku); } catch (e) { return DataError('خطا در پرداخت: $e'); } if (!result.success) { return DataError('خرید انجام نشد یا لغو شد'); } final verify = await purchaseUseCase(PurchaseParams( store: gateway.store, kind: event.kind, productId: event.productId, token: result.token, purchaseData: result.purchaseData, signature: result.signature, )); // پس از تأییدِ بک‌اند، خرید را در فروشگاه نهایی/مصرف می‌کنیم. if (verify is DataSuccess && result.onConfirmed != null) { try { await result.onConfirmed!(); } catch (_) {/* consume ناموفق حیاتی نیست */} } return verify; } Future _load(Emitter emit) async { emit(state.copyWith(loadStatus: ShopLoading())); final res = await getShopUseCase(const NoParams()); if (res is DataSuccess) { emit(state.copyWith(loadStatus: ShopLoaded(res.data!))); } else { emit(state.copyWith(loadStatus: ShopLoadError(res.error!))); } } /// اجرای یک عملیات، نمایش وضعیت و سپس بازخوانی کاتالوگ. Future _action( Emitter emit, Future> Function() action, ) async { if (state.busy) return; emit(state.copyWith(actionStatus: ActionLoading())); final res = await action(); if (res is DataSuccess) { emit(state.copyWith(actionStatus: ActionSuccess(res.data!))); await _load(emit); } else { emit(state.copyWith(actionStatus: ActionError(res.error!))); } } }