import 'package:concierge/data/remote/models/order.dart';
import 'package:concierge/domain/models/app_error.dart';
import 'package:concierge/domain/repositories/property_repository.dart';
import 'package:concierge/presentation/app/cart_cubit.dart';
import 'package:concierge/presentation/app/concierge_cubit.dart';
import 'package:concierge/presentation/base/base_cubit.dart';
import 'package:concierge/presentation/screens/payment/bloc/payment_state.dart';
import 'package:payment_plugin/payment_plugin.dart';
import 'package:payment_plugin/utils/json.dart';
import 'package:payment_plugin/presentation/app/bloc/payment_cubit.dart' as payment_plugin;
class PaymentCubit extends BaseCubit<PaymentState> {
final CartCubit _cartCubit;
final ConciergeCubit _conciergeCubit;
final PropertyRepository _propertyRepository;
final PaymentPlugin _paymentPlugin;
final payment_plugin.PaymentCubit _paymentCubit;
PaymentCubit(
this._cartCubit,
this._conciergeCubit,
this._propertyRepository,
this._paymentPlugin,
this._paymentCubit,
) : super(const PaymentState()) {
init();
_paymentCubit.stream.listen((state) {
if (state is PaymentProcessingStateConfirmed) {
_checkStatus();
}
});
}
Future<void> init() async {
try {
safeEmit(state.copyWith(isLoading: true, error: AppError.none));
final products = _cartCubit.state.productsWithQuantity.values.map(
(product) => {
"id": product.productId,
"quantity": product.quantity,
"options": [
...product.variant.entries.map(
(entry) => {
"id": entry.key,
"answers": [
{
"id": entry.value,
"is_selected": true,
},
],
},
),
],
},
);
final area = _cartCubit.state.selectedArea!;
final orderResponse = await _propertyRepository.createOrder(
products: products.toList(),
areaId: area.id,
roomNumber: _conciergeCubit.state.roomNumber,
isDelivery: _cartCubit.state.isDelivery,
locationCode: _cartCubit.state.deliveryLocationCode,
deliveryLocation: _cartCubit.state.deliveryLocation,
readyTime: _cartCubit.state.readyTime,
comment: _cartCubit.state.comment,
chargeToRoom: _cartCubit.state.chargeToRoom,
);
safeEmit(state.copyWith(orderId: orderResponse.id));
if (orderResponse.totalPrice > 0 || _cartCubit.state.chargeToRoom) {
final sessionResponse = await _paymentPlugin.repository.createAdyenSessionForConcierge(
orderResponse.id,
);
final data = Json.of(sessionResponse);
final clientKey = data["clientKey"];
final session = Json.of(data["sessionResponse"]);
final sessionData = session["sessionData"];
final sessionId = session["id"];
await _paymentCubit.createConciergeSession(sessionId, clientKey, sessionData);
} else {
_checkStatus();
}
} catch (e, st) {
handleError(e, st);
safeEmit(state.copyWith(error: AppError.unknown(e.toString())));
_paymentCubit.emitError(e);
} finally {
safeEmit(state.copyWith(isLoading: false));
}
}
Future<void> _checkStatus() async {
try {
final response = await _propertyRepository.getOrder(state.orderId);
if (response.status == OrderStatus.received) {
safeEmit(state.copyWith(paymentSuccess: true));
} else if (response.status == OrderStatus.cancelled) {
_paymentCubit.emitError("Operation cancelled");
} else {
await Future.delayed(Duration(seconds: 1));
_checkStatus();
}
} catch (e, st) {
_paymentCubit.emitError(e);
handleError(e, st);
}
}
}