import 'package:guru_app/financial/asset/assets_model.dart';
import 'package:guru_app/financial/product/product_model.dart';

/// Created by Haoyi on 6/1/21
///

class AssetsStore<T extends Asset> {
  final bool isActive;
  final Map<ProductId, T> data = <ProductId, T>{};

  AssetsStore.inactive() : isActive = false;

  AssetsStore() : isActive = true;

  Map<String, String> toStringMap() {
    final result = <String, String>{};
    int index = 0;
    for (var entry in data.entries) {
      result["${index++}"] = entry.toString();
    }
    return result;
  }

  void forEach(void Function(ProductId productId, T asset) callback) {
    for (var element in data.entries) {
      callback.call(element.key, element.value);
    }
  }

  void removeWhere(bool Function(ProductId productId, T asset) callback) {
    data.removeWhere((key, value) => callback.call(key, value));
  }

  void addAsset(T asset) {
    data[asset.productId] = asset;
  }

  void clearAsset({String? category, TransactionMethod? method}) {
    data.removeWhere((key, value) =>
        (category == null || value.order.category == category) &&
        (method == null || value.order.method == method.index));
  }

  void addAllAssets(List<T> assets) {
    for (var asset in assets) {
      addAsset(asset);
    }
  }

  T? getAsset(ProductId? productId) {
    return productId?.isValid() == true ? data[productId] : null;
  }

  bool isOwned(ProductId productId) {
    return data.containsKey(productId);
  }

  bool existsAssets(Iterable<ProductId> productIds) {
    for (var productId in productIds) {
      if (isOwned(productId)) {
        return true;
      }
    }
    return false;
  }

  AssetsStore<T> clone() {
    return AssetsStore()..data.addAll(data);
  }
}
