export class Node {
  constructor(tree, item, parent, isPlaceHolder = false) {
    this.children = new Map();
    this.visible = true;
    this.item = item;
    this.parent = parent;
    this._tree = tree;
    this.isPlaceHolder = isPlaceHolder;
    if (item && !isPlaceHolder) {
      this._isLazyLoad = typeof item.children === "function" || item.childrenCount > 0;
      if (Array.isArray(item.children)) {
        Array.from(item.children).forEach(item => this.addChild(this._tree, item));
        this._childrenLoaded = true;
      }
    }
    else {
      this._isLazyLoad = false;
      this._childrenLoaded = true;
    }
  }
  refresh(newItem) {
    if (this.isPlaceHolder) {
      return;
    }
    this.item = Object.assign({}, newItem);
    this._isLazyLoad = typeof this.item.children === "function" || this.item.childrenCount > 0;
    const oldChildren = this.children;
    this.children = new Map();
    if (Array.isArray(this.item.children)) {
      if (this.item.expanded === undefined) {
        this.item.expanded = true;
      }
      Array.from(this.item.children).forEach(item => {
        const node = oldChildren.get(item.id);
        if (node) {
          if (item.expanded === undefined) {
            item.expanded = node.item.expanded;
          }
          node.refresh(item);
          this.children.set(item.id, node);
        }
        else {
          if (item.expanded === undefined) {
            item.expanded = true;
          }
          this.addChild(this._tree, Object.assign({}, item));
        }
      });
      this._childrenLoaded = true;
    }
    else {
      this._childrenLoaded = false;
    }
  }
  isDisabled() {
    if (this.isPlaceHolder) {
      return false;
    }
    return this._tree.isNodeDisabled(this.item.id, this.item.disabled);
  }
  updateChildren(children) {
    if (this.isPlaceHolder) {
      return;
    }
    this.refresh(Object.assign(Object.assign({}, this.item), { children }));
  }
  addChild(tree, item) {
    if (!this.children.has(item.id)) {
      this.children.set(item.id, new Node(tree, item, this));
    }
  }
  removeChild(id) {
    if (this.children.has(id)) {
      this.children.delete(id);
      return true;
    }
    return false;
  }
  addPlaceHolder() {
    this.children.clear();
    const id = this.item.id;
    this.children.set(id, new Node(undefined, { id: `placeholder_${id}`, label: "Carregando..." }, this, true));
  }
  getNode(id) {
    if (this.children.has(id)) {
      return this.children.get(id);
    }
    const childrenArray = Array.from(this.children.values());
    for (const child of childrenArray) {
      const result = child.getNode(id);
      if (result) {
        return result;
      }
    }
  }
  needLoad() {
    return this._isLazyLoad && !this._childrenLoaded;
  }
  isExpandable() {
    if (this._isLazyLoad) {
      return true;
    }
    if (this.children.size > 0) {
      return true;
    }
    return false;
  }
  getChildren() {
    if (this.isPlaceHolder) {
      return [];
    }
    if (this.needLoad()) {
      this._tree.loadChildren(this);
    }
    return Array.from(this.children.values());
  }
}
