var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { MapToComponentField, MapToComponentMethod, VegaSlimmer } from 'vega-slimmer/core';
import ChangeManager from '../../change-manager/change-manager';
import domNodeSubjectFactory from '../../change-manager/subject/dom-node-subject/dom-node-subject-factory';
import { findParent } from '../../../utils/ui';
import { VegaInternalNestEAHierarchyTreeChange } from '../../event-manager/event-id/vega-internal-event-id';
import { DomNodeSubjectObserverFactory } from '../../change-manager/subject/dom-node-subject/dom-node-subject-observer-factory';
var NestEANotifyType;
(function (NestEANotifyType) {
  NestEANotifyType["SHOW"] = "show";
  NestEANotifyType["HIDE"] = "hide";
})(NestEANotifyType || (NestEANotifyType = {}));
/**
 * Dynamically add parents and children of nest element appender while it show or hide.
 */
export class ElementAppenderHierarchyTreeManager extends VegaSlimmer {
  constructor(currentEA) {
    super();
    this.childrenEA = [];
    this.currentEA = currentEA;
  }
  /**
   * Listen current element appender did load.
   */
  componentDidLoad() {
    this.register();
  }
  /**
   * Listen current element appender show.
   */
  onShow() {
    this.notify(NestEANotifyType.SHOW);
  }
  /**
   * Listen current element appender hide.
   */
  onHide() {
    this.notify(NestEANotifyType.HIDE);
  }
  /**
   * Get current parent of element appender.
   *
   * @returns {Nullable<ElementAppenderSlimmer>} - parent.
   */
  getParent() {
    return this.parentEA;
  }
  /**
   * Get current children of element appender.
   *
   * @returns {ElementAppenderSlimmer[]} - children.
   */
  getChildren() {
    return this.childrenEA;
  }
  /**
   * While current element appender show or hide we should notify nest element appender to add or remove chain.
   *
   * @param {NestEANotifyType} type - Notify type.
   */
  notify(type) {
    const parent = findParent(this.showConfig.target, '.vega-element-appender-appendable');
    if (parent) {
      ChangeManager.notify(domNodeSubjectFactory.getSubject(parent, VegaInternalNestEAHierarchyTreeChange), {
        type: type,
        child: this.currentEA,
        callback: 
        /* eslint-disable jsdoc/require-jsdoc */
        (parentEASlimmer) => {
          this.parentEA = parentEASlimmer;
        },
      });
    }
  }
  /**
   * Add a change manager to observer the nest element appender show or hide.
   */
  register() {
    if (this.showConfig) {
      DomNodeSubjectObserverFactory.addUniqueObserverToNode(this.showConfig.appendableElement, VegaInternalNestEAHierarchyTreeChange, (payload) => {
        if (payload.type === NestEANotifyType.SHOW) {
          this.childrenEA.push(payload.child);
        }
        else if (payload.type === NestEANotifyType.HIDE) {
          this.childrenEA = this.childrenEA.filter((child) => child !== payload.child);
        }
        payload.callback(this.currentEA);
      });
    }
  }
}
__decorate([
  MapToComponentField()
], ElementAppenderHierarchyTreeManager.prototype, "showConfig", void 0);
__decorate([
  MapToComponentMethod('componentDidLoad')
], ElementAppenderHierarchyTreeManager.prototype, "componentDidLoad", null);
__decorate([
  MapToComponentMethod('show')
], ElementAppenderHierarchyTreeManager.prototype, "onShow", null);
__decorate([
  MapToComponentMethod('hide')
], ElementAppenderHierarchyTreeManager.prototype, "onHide", null);
