import 'timeline_entry.dart';

class EntryTreeItem {
  final TimelineEntry entry;
  final bool isMine;
  bool isOrphaned;

  final _children = <String, EntryTreeItem>{};

  EntryTreeItem(this.entry,
      {this.isMine = true,
      this.isOrphaned = false,
      Map<String, EntryTreeItem>? initialChildren}) {
    _children.addAll(initialChildren ?? {});
  }

  factory EntryTreeItem.empty() => EntryTreeItem(TimelineEntry());

  EntryTreeItem copy({required TimelineEntry entry}) => EntryTreeItem(
        entry,
        isMine: isMine,
        isOrphaned: isOrphaned,
        initialChildren: _children,
      );

  String get id => entry.id;

  void addOrUpdate(EntryTreeItem child) {
    _children[child.id] = child;
  }

  EntryTreeItem? getChildById(String id) {
    if (_children.containsKey(id)) {
      return _children[id]!;
    }

    for (final c in _children.values) {
      final result = c.getChildById(id);
      if (result != null) {
        return result;
      }
    }

    return null;
  }

  void removeChildById(String id) {
    if (_children.containsKey(id)) {
      _children.remove(id);
    }

    for (final c in _children.values) {
      c.removeChildById(id);
    }

    return;
  }

  int get totalChildren {
    int t = _children.length;
    for (final c in _children.values) {
      t += c.totalChildren;
    }

    return t;
  }

  List<EntryTreeItem> get children => List.unmodifiable(_children.values);

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is EntryTreeItem &&
          runtimeType == other.runtimeType &&
          entry == other.entry &&
          isMine == other.isMine &&
          isOrphaned == other.isOrphaned &&
          _children == other._children;

  @override
  int get hashCode =>
      entry.hashCode ^
      isMine.hashCode ^
      isOrphaned.hashCode ^
      _children.hashCode;
}
