import 'package:flutter/foundation.dart'; import 'package:pshared/controllers/balance_mask/wallets.dart'; import 'package:pshared/provider/ledger.dart'; import 'package:pweb/pages/dashboard/buttons/balance/balance_item.dart'; class BalanceCarouselController with ChangeNotifier { WalletsController? _walletsController; List _items = const [BalanceItem.addAction()]; int _index = 0; List get items => _items; int get index => _index; void update({ required WalletsController walletsController, required LedgerAccountsProvider ledgerProvider, }) { _walletsController = walletsController; final nextItems = [ ...walletsController.wallets.map(BalanceItem.wallet), ...ledgerProvider.accounts.map(BalanceItem.ledger), const BalanceItem.addAction(), ]; final nextIndex = _resolveNextIndex(nextItems, walletsController); final hasItemsChanged = !_isSameItems(_items, nextItems); final hasIndexChanged = _index != nextIndex; _items = nextItems; _index = nextIndex; if (hasItemsChanged || hasIndexChanged) { notifyListeners(); } } void onPageChanged(int value) { final next = _clampIndex(value, _items.length); if (_index == next) { _syncSelectedWallet(); return; } _index = next; _syncSelectedWallet(); notifyListeners(); } void goBack() => onPageChanged(_index - 1); void goForward() => onPageChanged(_index + 1); int _resolveNextIndex( List nextItems, WalletsController walletsController, ) { final currentWalletRef = _currentWalletRef(_items, _index); if (currentWalletRef != null) { final byCurrentWallet = _walletIndexByRef(nextItems, currentWalletRef); if (byCurrentWallet != null) return byCurrentWallet; final selectedWalletRef = walletsController.selectedWalletRef; final bySelectedWallet = _walletIndexByRef(nextItems, selectedWalletRef); if (bySelectedWallet != null) return bySelectedWallet; } return _clampIndex(_index, nextItems.length); } String? _currentWalletRef(List items, int index) { if (items.isEmpty || index < 0 || index >= items.length) return null; final current = items[index]; if (!current.isWallet) return null; return current.wallet?.id; } int? _walletIndexByRef(List items, String? walletRef) { if (walletRef == null || walletRef.isEmpty) return null; final idx = items.indexWhere( (item) => item.isWallet && item.wallet?.id == walletRef, ); if (idx < 0) return null; return idx; } int _clampIndex(int value, int itemCount) { if (itemCount <= 0) return 0; return value.clamp(0, itemCount - 1); } bool _isSameItems(List left, List right) { if (left.length != right.length) return false; for (var i = 0; i < left.length; i++) { final a = left[i]; final b = right[i]; if (a.type != b.type) return false; if (_itemIdentity(a) != _itemIdentity(b)) return false; } return true; } String _itemIdentity(BalanceItem item) => switch (item.type) { BalanceItemType.wallet => item.wallet?.id ?? '', BalanceItemType.ledger => item.account?.ledgerAccountRef ?? '', BalanceItemType.addAction => 'add', }; void _syncSelectedWallet() { final walletsController = _walletsController; if (walletsController == null || _items.isEmpty) return; final current = _items[_index]; if (!current.isWallet || current.wallet == null) return; final wallet = current.wallet!; if (walletsController.selectedWallet?.id == wallet.id) return; walletsController.selectWallet(wallet); } }