import 'package:flutter/foundation.dart'; import 'package:pshared/models/payment/payment.dart'; import 'package:pshared/provider/payment/multiple/provider.dart'; import 'package:pshared/provider/payment/payments.dart'; import 'package:pshared/provider/payment/provider.dart'; class PaymentsUpdatesProvider extends ChangeNotifier { PaymentsProvider? _payments; PaymentProvider? _paymentProvider; MultiPaymentProvider? _multiPaymentProvider; Set _knownKeys = {}; void update({ required PaymentsProvider paymentsProvider, required PaymentProvider paymentProvider, required MultiPaymentProvider multiPaymentProvider, }) { if (!identical(_payments, paymentsProvider)) { _payments = paymentsProvider; _syncKnownKeys(); } if (!identical(_paymentProvider, paymentProvider)) { _paymentProvider?.removeListener(_onSinglePaymentChanged); _paymentProvider = paymentProvider; _paymentProvider?.addListener(_onSinglePaymentChanged); } if (!identical(_multiPaymentProvider, multiPaymentProvider)) { _multiPaymentProvider?.removeListener(_onMultiPaymentChanged); _multiPaymentProvider = multiPaymentProvider; _multiPaymentProvider?.addListener(_onMultiPaymentChanged); } _syncKnownKeys(); } void _syncKnownKeys() { _knownKeys = { for (final payment in _payments?.payments ?? const []) ..._keyFor(payment), }; } void _onSinglePaymentChanged() { final payment = _paymentProvider?.payment; if (payment == null) return; final key = _key(payment); if (key != null && _knownKeys.contains(key)) return; _merge([payment]); } void _onMultiPaymentChanged() { final payments = _multiPaymentProvider?.payments ?? const []; if (payments.isEmpty) return; final incoming = []; for (final payment in payments) { final key = _key(payment); if (key == null || !_knownKeys.contains(key)) { incoming.add(payment); } } if (incoming.isEmpty) return; _merge(incoming); } void _merge(List incoming) { if (incoming.isEmpty) return; _payments?.mergePayments(incoming); for (final payment in incoming) { final key = _key(payment); if (key != null) { _knownKeys.add(key); } } } String? _key(Payment payment) { final ref = payment.paymentRef?.trim(); if (ref != null && ref.isNotEmpty) return ref; final idempotency = payment.idempotencyKey?.trim(); if (idempotency != null && idempotency.isNotEmpty) return idempotency; return null; } Iterable _keyFor(Payment payment) sync* { final key = _key(payment); if (key != null) yield key; } @override void dispose() { _paymentProvider?.removeListener(_onSinglePaymentChanged); _multiPaymentProvider?.removeListener(_onMultiPaymentChanged); super.dispose(); } }