import 'package:be_happy/domain/usecase/get_profile_usecase.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

import '../../core/result.dart';
import '../../core/failures.dart';
import '../../domain/entities/payment_card.dart';
import '../../domain/usecase/get_payment_cards_usecase.dart';
import '../../domain/usecase/remove_payment_card_usecase.dart';
import '../../domain/usecase/set_main_payment_card_usecase.dart';
import '../event/payment_methods_event.dart';
import '../state/payment_methods_state.dart';

class PaymentMethodsBloc extends Bloc<PaymentMethodsEvent, PaymentMethodsState> {
  final GetPaymentCardsUsecase _getPaymentCardsUsecase;
  final RemovePaymentCardUsecase _removePaymentCardUsecase;
  final SetMainPaymentCardUsecase _setMainPaymentCardUsecase;
  final GetProfileUseCase _getProfileUseCase;

  PaymentMethodsBloc(
    this._getPaymentCardsUsecase,
    this._removePaymentCardUsecase,
    this._setMainPaymentCardUsecase,
    this._getProfileUseCase,
  ) : super(PaymentMethodsState(status: PaymentMethodsStatus.initial)) {
    on<PaymentMethodsStarted>(_onStarted);
    on<PaymentMethodsDeleteCard>(_onDeleteCard);
    on<PaymentMethodsSetMainCard>(_onSetMainCard);
  }

  Future<void> _onStarted(
    PaymentMethodsStarted event,
    Emitter<PaymentMethodsState> emit,
  ) async {
    emit(state.copyWith(status: PaymentMethodsStatus.loading));

    try {
      final result = await _getPaymentCardsUsecase();
      final profile = await _getProfileUseCase();


      if (result is Success<List<PaymentCard>>) {
        emit(state.copyWith(
          status: PaymentMethodsStatus.success,
          cards: result.data ?? [],
          balance: profile.balance,
        ));
      } else if (result is Failure) {
        String errorMessage = 'Не удалось загрузить карты';
        
        /*if (result.failure is AuthFailure) {
          errorMessage = 'Ошибка авторизации';
        } else if (result.failure is UnknownFailure) {
          errorMessage = result.failure.message ?? 'Неизвестная ошибка';
        }*/
        
        emit(state.copyWith(
          status: PaymentMethodsStatus.failure,
          errorMessage: errorMessage,
        ));
      }
    } catch (e) {
      emit(state.copyWith(
        status: PaymentMethodsStatus.failure,
        errorMessage: e.toString(),
      ));
    }
  }

  Future<void> _onDeleteCard(
    PaymentMethodsDeleteCard event,
    Emitter<PaymentMethodsState> emit,
  ) async {
    emit(state.copyWith(
      status: PaymentMethodsStatus.loading,
      isDeleting: true,
    ));

    try {
      final result = await _removePaymentCardUsecase(event.cardId);

      if (result is Success) {
        emit(state.copyWith(isDeleting: false, status: PaymentMethodsStatus.success));
        add(PaymentMethodsStarted());
      } else if (result is Failure) {
        String errorMessage = 'Не удалось удалить карту';
        
        if (result.failure is AuthFailure) {
          errorMessage = 'Ошибка авторизации';
        } else if (result.failure is UnknownFailure) {
          errorMessage = result.failure.message ?? 'Неизвестная ошибка';
        }
        
        emit(state.copyWith(
          isDeleting: false,
          errorMessage: errorMessage,
        ));
      }
    } catch (e) {
      emit(state.copyWith(
        isDeleting: false,
        errorMessage: e.toString(),
      ));
    }
  }

  Future<void> _onSetMainCard(
    PaymentMethodsSetMainCard event,
    Emitter<PaymentMethodsState> emit,
  ) async {
    emit(state.copyWith(isSettingMain: true));

    try {
      final result = await _setMainPaymentCardUsecase(event.cardId);

      if (result is Success) {
        emit(state.copyWith(isSettingMain: false));
        add(PaymentMethodsStarted());
      } else if (result is Failure) {
        String errorMessage = 'Не удалось установить основную карту';
        
        if (result.failure is AuthFailure) {
          errorMessage = 'Ошибка авторизации';
        } else if (result.failure is UnknownFailure) {
          errorMessage = result.failure.message ?? 'Неизвестная ошибка';
        }
        
        emit(state.copyWith(
          isSettingMain: false,
          errorMessage: errorMessage,
        ));
      }
    } catch (e) {
      emit(state.copyWith(
        isSettingMain: false,
        errorMessage: e.toString(),
      ));
    }
  }
}
