import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:pshared/models/payment/wallet.dart'; import 'package:pshared/provider/organizations.dart'; import 'package:pshared/provider/resource.dart'; import 'package:pshared/service/payment/wallets.dart'; import 'package:pshared/utils/exception.dart'; class WalletsProvider with ChangeNotifier { final WalletsService _service; late OrganizationsProvider _organizations; WalletsProvider(this._service); Resource> _resource = Resource(data: []); Resource> get resource => _resource; List get wallets => _resource.data ?? []; bool get isLoading => _resource.isLoading; Exception? get error => _resource.error; Wallet? _selectedWallet; Wallet? get selectedWallet => _selectedWallet; final bool _isHidden = true; bool get isHidden => _isHidden; bool _isRefreshingBalances = false; bool get isRefreshingBalances => _isRefreshingBalances; void update(OrganizationsProvider organizations) { _organizations = organizations; if (_organizations.isOrganizationSet) loadWalletsWithBalances(); } Future updateWallet(Wallet newWallet) { throw Exception('update wallet is not implemented'); } void selectWallet(Wallet wallet) => _setSelectedWallet(wallet); Future loadWalletsWithBalances() async { _setResource(_resource.copyWith(isLoading: true, error: null)); try { final base = await _service.getWallets(_organizations.current.id); final withBalances = []; for (final wallet in base) { try { final balance = await _service.getBalance(_organizations.current.id, wallet.id); withBalances.add(wallet.copyWith(balance: balance)); } catch (e) { _setResource(_resource.copyWith(error: toException(e))); withBalances.add(wallet); } } _setResource(Resource(data: withBalances, isLoading: false, error: _resource.error)); } catch (e) { _setResource(_resource.copyWith(isLoading: false, error: toException(e))); } } Future refreshBalances() async { if (wallets.isEmpty) return; _isRefreshingBalances = true; notifyListeners(); try { final updated = []; for (final wallet in wallets) { final balance = await _service.getBalance(_organizations.current.id, wallet.id); updated.add(wallet.copyWith(balance: balance)); } _setResource(_resource.copyWith(data: updated)); } catch (e) { _setResource(_resource.copyWith(error: toException(e))); } finally { _isRefreshingBalances = false; notifyListeners(); } } void toggleVisibility(String walletId) { final index = wallets.indexWhere((w) => w.id == walletId); if (index < 0) return; final wallet = wallets[index]; final updated = wallet.copyWith(isHidden: !wallet.isHidden); final next = List.from(wallets); next[index] = updated; _setResource(_resource.copyWith(data: next)); if (_selectedWallet?.id == walletId) { _selectedWallet = updated; } } void _setResource(Resource> newResource) { _resource = newResource; _selectedWallet = _resolveSelectedWallet(_selectedWallet, wallets); notifyListeners(); } Wallet? _resolveSelectedWallet(Wallet? current, List available) { if (available.isEmpty) return null; final currentId = current?.id; if (currentId != null) { final existing = available.firstWhereOrNull((wallet) => wallet.id == currentId); if (existing != null) return existing; } return available.firstWhereOrNull((wallet) => !wallet.isHidden) ?? available.first; } void _setSelectedWallet(Wallet wallet) { if (_selectedWallet?.id == wallet.id && _selectedWallet?.isHidden == wallet.isHidden) { return; } _selectedWallet = wallet; notifyListeners(); } }