import 'package:flutter_bloc/flutter_bloc.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<ShopEvent, ShopBlocState> {
  final GetShopUseCase getShopUseCase;
  final BuyCardUseCase buyCardUseCase;
  final SelectCardUseCase selectCardUseCase;
  final PurchaseUseCase purchaseUseCase;
  final AdRewardUseCase adRewardUseCase;

  ShopBloc(
    this.getShopUseCase,
    this.buyCardUseCase,
    this.selectCardUseCase,
    this.purchaseUseCase,
    this.adRewardUseCase,
  ) : super(ShopBlocState.initial()) {
    on<LoadShopEvent>((event, emit) => _load(emit));

    on<BuyCardEvent>((event, emit) =>
        _action(emit, () => buyCardUseCase(event.cardId)));

    on<SelectCardEvent>((event, emit) =>
        _action(emit, () => selectCardUseCase(event.cardId)));

    on<PurchaseEvent>((event, emit) => _action(
        emit,
        () => purchaseUseCase(PurchaseParams(
              store: 'bazaar',
              kind: event.kind,
              productId: event.productId,
              token:
                  'dev-${event.kind}-${event.productId}-${DateTime.now().millisecondsSinceEpoch}',
            ))));

    on<AdRewardEvent>((event, emit) => _action(
          emit,
          () async {
            final res = await adRewardUseCase(
                'dev-ad-${DateTime.now().millisecondsSinceEpoch}');
            if (res is DataSuccess) {
              return const DataSuccess('سکه رایگان دریافت شد');
            }
            return DataError<String>(res.error!);
          },
        ));
  }

  Future<void> _load(Emitter<ShopBlocState> 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<void> _action(
    Emitter<ShopBlocState> emit,
    Future<DataState<String>> 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!)));
    }
  }
}
