import '../../admin/domain/admin_category_node.dart';

int? tryParseDynamicInt(dynamic value) {
  if (value == null) return null;
  if (value is int) return value;
  if (value is num) return value.toInt();
  if (value is String) return int.tryParse(value.trim());
  return null;
}

class InventoryCategoryBranchIndex {
  final Map<int, Set<int>> _descendantsById;

  InventoryCategoryBranchIndex._(this._descendantsById);

  factory InventoryCategoryBranchIndex.fromTree(List<AdminCategoryNode> roots) {
    final descendantsById = <int, Set<int>>{};

    Set<int> collect(AdminCategoryNode node) {
      final ids = <int>{node.id};
      for (final child in node.children) {
        ids.addAll(collect(child));
      }
      descendantsById[node.id] = ids;
      return ids;
    }

    for (final root in roots) {
      collect(root);
    }

    return InventoryCategoryBranchIndex._(descendantsById);
  }

  Set<int>? branchIdsFor(int? categoryId) {
    if (categoryId == null) return null;
    return _descendantsById[categoryId] ?? {categoryId};
  }
}

bool productInSelectedBranch({
  required int? productCategoryId,
  required Set<int>? selectedCategoryIds,
}) {
  if (selectedCategoryIds == null) return true;
  if (productCategoryId == null) return false;
  return selectedCategoryIds.contains(productCategoryId);
}

class InventorySortedProductsCache {
  String? _lastKey;
  List<Map<String, dynamic>> _lastSorted = const [];

  List<Map<String, dynamic>> sort(List<Map<String, dynamic>> products) {
    final key = _buildKey(products);
    if (_lastKey == key) return _lastSorted;

    final sorted = [...products]
      ..sort((a, b) {
        final aName = (a['canonicalName'] ?? a['name'] ?? '').toString().toLowerCase();
        final bName = (b['canonicalName'] ?? b['name'] ?? '').toString().toLowerCase();
        return aName.compareTo(bName);
      });

    _lastKey = key;
    _lastSorted = sorted;
    return _lastSorted;
  }

  String _buildKey(List<Map<String, dynamic>> products) {
    final b = StringBuffer('${products.length}|');
    for (final p in products) {
      final id = tryParseDynamicInt(p['id']) ?? -1;
      final categoryId = tryParseDynamicInt(p['categoryId']) ?? -1;
      final name = (p['canonicalName'] ?? p['name'] ?? '').toString();
      b
        ..write(id)
        ..write(':')
        ..write(categoryId)
        ..write(':')
        ..write(name)
        ..write('|');
    }
    return b.toString();
  }
}
