import 'package:flutter/foundation.dart'; import 'package:pshared/controllers/balance_mask/wallets.dart'; import 'package:pshared/models/ledger/account.dart'; import 'package:pshared/models/payment/source_type.dart'; import 'package:pshared/models/payment/wallet.dart'; import 'package:pshared/provider/ledger.dart'; import 'package:pshared/utils/currency.dart'; class PaymentSourceController with ChangeNotifier { WalletsController? _walletsController; List _wallets = const []; Map _walletsById = const {}; List _ledgerAccounts = const []; Map _ledgerByRef = const {}; PaymentSourceType? _selectedType; String? _selectedRef; List get wallets => _wallets; List get ledgerAccounts => _ledgerAccounts; bool get hasSources => _wallets.isNotEmpty || _ledgerAccounts.isNotEmpty; PaymentSourceType? get selectedType => _selectedType; String? get selectedRef => _selectedRef; Wallet? get selectedWallet { if (_selectedType != PaymentSourceType.wallet) return null; final ref = _selectedRef; if (ref == null) return null; return _walletsById[ref]; } LedgerAccount? get selectedLedgerAccount { if (_selectedType != PaymentSourceType.ledger) return null; final ref = _selectedRef; if (ref == null) return null; return _ledgerByRef[ref]; } String? get selectedCurrencyCode { final wallet = selectedWallet; if (wallet != null) { return currencyCodeToString(wallet.currency); } final ledger = selectedLedgerAccount; if (ledger != null) { final code = ledger.currency.trim().toUpperCase(); return code.isEmpty ? null : code; } return null; } void update(WalletsController wallets, LedgerAccountsProvider ledger) { _walletsController = wallets; _walletsById = _uniqueWalletsById(wallets.wallets); _wallets = _walletsById.values.toList(growable: false); _ledgerByRef = _uniqueLedgerByRef(ledger.accounts); _ledgerAccounts = _ledgerByRef.values.toList(growable: false); _syncSelection(); notifyListeners(); } void selectWallet(Wallet wallet) { selectWalletByRef(wallet.id); } void selectWalletByRef(String walletRef) { if (!_walletsById.containsKey(walletRef)) return; _walletsController?.selectWalletByRef(walletRef); _setSelection(PaymentSourceType.wallet, walletRef); } void selectLedgerByRef(String ledgerAccountRef) { if (!_ledgerByRef.containsKey(ledgerAccountRef)) return; _setSelection(PaymentSourceType.ledger, ledgerAccountRef); } bool isWalletSelected(String walletRef) { return _selectedType == PaymentSourceType.wallet && _selectedRef == walletRef; } bool isLedgerSelected(String ledgerAccountRef) { return _selectedType == PaymentSourceType.ledger && _selectedRef == ledgerAccountRef; } void _syncSelection() { final currentType = _selectedType; final currentRef = _selectedRef; if (currentType == PaymentSourceType.wallet && currentRef != null && _walletsById.containsKey(currentRef)) { return; } if (currentType == PaymentSourceType.ledger && currentRef != null && _ledgerByRef.containsKey(currentRef)) { return; } final selectedWalletRef = _walletsController?.selectedWalletRef; if (selectedWalletRef != null && _walletsById.containsKey(selectedWalletRef)) { _selectedType = PaymentSourceType.wallet; _selectedRef = selectedWalletRef; return; } if (_wallets.isNotEmpty) { _selectedType = PaymentSourceType.wallet; _selectedRef = _wallets.first.id; return; } if (_ledgerAccounts.isNotEmpty) { _selectedType = PaymentSourceType.ledger; _selectedRef = _ledgerAccounts.first.ledgerAccountRef; return; } _selectedType = null; _selectedRef = null; } void _setSelection(PaymentSourceType type, String ref) { if (_selectedType == type && _selectedRef == ref) return; _selectedType = type; _selectedRef = ref; notifyListeners(); } Map _uniqueWalletsById(List wallets) { final result = {}; for (final wallet in wallets) { result.putIfAbsent(wallet.id, () => wallet); } return result; } Map _uniqueLedgerByRef(List accounts) { final result = {}; for (final account in accounts) { result.putIfAbsent(account.ledgerAccountRef, () => account); } return result; } }