import 'package:flutter/foundation.dart';

import 'package:pshared/models/payment/wallet.dart';
import 'package:pshared/provider/payment/wallets.dart';


class WalletsController with ChangeNotifier {
  late WalletsProvider _wallets;

  String? _orgRef;

  /// UI-only: wallet refs with masked balances
  final Set<String> _maskedBalanceWalletRefs = <String>{};
  Set<String> _knownWalletRefs = <String>{};

  List<Wallet> _walletsList = <Wallet>[];
  Map<String, Wallet> _walletsById = <String, Wallet>{};

  String? _selectedWalletRef;

  bool get isLoading => _wallets.isLoading;
  Exception? get error => _wallets.error;

  void update(WalletsProvider wallets) {
    _wallets = wallets;

    final nextOrgRef = wallets.organizationRef;
    final orgChanged = nextOrgRef != _orgRef;

    if (orgChanged) {
      _orgRef = nextOrgRef;
      _maskedBalanceWalletRefs.clear();
      _knownWalletRefs = <String>{};
      _selectedWalletRef = null;
    }

    _walletsById = _uniqueWalletsById(wallets.wallets);
    _walletsList = _walletsById.values.toList(growable: false);

    // Remove ids that no longer exist
    final ids = _walletsById.keys.toSet();
    _maskedBalanceWalletRefs.removeWhere((id) => !ids.contains(id));

    final newIds = ids.difference(_knownWalletRefs);
    if (newIds.isNotEmpty) {
      _maskedBalanceWalletRefs.addAll(newIds);
    }
    _knownWalletRefs = ids;

    _selectedWalletRef = _resolveSelectedId(
      currentRef: _selectedWalletRef,
      wallets: _walletsList,
    );

    notifyListeners();
  }

  List<Wallet> get wallets => _walletsList;

  bool isBalanceMasked(String walletRef) => _maskedBalanceWalletRefs.contains(walletRef);
  bool isBalanceVisible(String walletRef) => !isBalanceMasked(walletRef);

  List<Wallet> get unmaskedWallets =>
      wallets.where((w) => !_maskedBalanceWalletRefs.contains(w.id)).toList(growable: false);

  Wallet? get selectedWallet {
    final id = _selectedWalletRef;
    if (id == null) return null;
    return _walletsById[id];
  }

  String? get selectedWalletRef => _selectedWalletRef;

  void selectWallet(Wallet wallet) => selectWalletByRef(wallet.id);

  void selectWalletByRef(String walletRef) {
    if (_selectedWalletRef == walletRef) return;

    _selectedWalletRef = walletRef;
    notifyListeners();
  }

  /// Toggle wallet balance masking
  void toggleBalanceMask(String walletRef) {
    final existed = _maskedBalanceWalletRefs.remove(walletRef);
    if (!existed) _maskedBalanceWalletRefs.add(walletRef);
    notifyListeners();
  }

  /// Unmask balances for all wallets (bulk action)
  void unmaskAllBalances() {
    _maskedBalanceWalletRefs.clear();
    notifyListeners();
  }

  String? _resolveSelectedId({
    required String? currentRef,
    required List<Wallet> wallets,
  }) {
    if (wallets.isEmpty) return null;

    // Keep current selection if it still exists
    if (currentRef != null && wallets.any((w) => w.id == currentRef)) {
      return currentRef;
    }

    // Fallback to the first wallet
    return wallets.first.id;
  }

  Map<String, Wallet> _uniqueWalletsById(List<Wallet> wallets) {
    final result = <String, Wallet>{};
    for (final wallet in wallets) {
      result.putIfAbsent(wallet.id, () => wallet);
    }
    return result;
  }
}
