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 { InjectVegaSlimmer, MapToComponentField, MapToComponentMethod, VegaSlimmer, methodPlaceholder, } from 'vega-slimmer/core';
import { MutationObserverSlimmer } from '../../../../helpers/slimmers/mutation-observer/mutation-observer-slimmer';
import ChangeManager from '../../../../helpers/change-manager/change-manager';
import DomNodeSubjectFactory from '../../../../helpers/change-manager/subject/dom-node-subject/dom-node-subject-factory';
import { VegaInternalDropdownTemplateItemsChange } from '../../../../helpers/event-manager/event-id/vega-internal-event-id';
/**
 * The controller for the table children components.
 */
export class VegaDropdownChildrenController extends VegaSlimmer {
  constructor() {
    super(...arguments);
    this.mutationObserver = new MutationObserverSlimmer({
      // eslint-disable-next-line jsdoc/require-jsdoc
      target: () => this.renderer.getDropdownContentBoxRef(),
      options: {
        childList: true,
        subtree: true,
      },
      /*
       * The below method is e2e-test covered in
       * @see{module:vega-dropdown-items-dom-change-e2e}
       */
      // eslint-disable-next-line jsdoc/require-jsdoc
      callback: /* istanbul ignore next */ () => this.syncUpDropdownCurrentData(),
    });
    this.labelSet = new Set();
    this.keySet = new Set();
    /**
     * The `syncUpDropdownCurrentDataBySlot` method is responsible for
     * synchronizing the current data in a dropdown based on the items present in the slot.
     */
    this.collectKeyAndLabelFromSlot = () => {
      const container = this.renderer.getDropdownContentBoxRef() || this.host;
      Array.from(container.querySelectorAll('vega-dropdown-item')).forEach((item) => {
        item.label && this.labelSet.add(item.label);
        item.itemKey && this.keySet.add(item.itemKey);
      });
    };
  }
  /**
   * Component lifecycle - [disconnectedCallback]
   */
  /* istanbul ignore next */
  disconnectedCallback() {
    methodPlaceholder();
  }
  /**
   * Component lifecycle - [componentWillLoad]
   */
  componentWillLoad() {
    this.syncUpDropdownCurrentData();
  }
  /**
   * Component lifecycle - [componentDidLoad]
   */
  componentDidLoad() {
    methodPlaceholder();
  }
  /**
   * The function "watchSource" synchronizes the dropdown current data.
   */
  watchSource() {
    if (this.renderModeController.isSourceRenderMode()) {
      this.syncUpDropdownCurrentData();
    }
  }
  /**
   * The function checks if a given label exists in a label set.
   *
   * @param {string} label - A string representing the label to check if it exists.
   * @returns {boolean} A boolean value is being returned.
   */
  isLabelExist(label) {
    return this.labelSet.has(label);
  }
  /**
   * The function checks if a given key exists in a set.
   *
   * @param {string} key - A string representing the key to check if it exists in the keySet.
   * @returns {boolean} A boolean value indicating whether the given key exists in the keySet.
   */
  isKeyExist(key) {
    return this.keySet.has(key);
  }
  /**
   * The function syncs up the current data of a dropdown based on the render mode.
   */
  syncUpDropdownCurrentData() {
    this.clearDropdownCurrentData();
    if (this.renderModeController.isSourceRenderMode()) {
      this.collectKeyAndLabelFromSource(this.source);
    }
    else {
      this.collectKeyAndLabelFromSlot();
      this.notifyTemplateItemsChange();
    }
  }
  /**
   * The function collects unique labels and keys from a nested array of objects.
   *
   * @param {VegaDropdownSourceItem[]} items - An array of objects representing dropdown source items.
   * Each object should have a "label" property representing the label of the dropdown option, and a
   * "key" property representing the value of the dropdown option. Additionally, each object can have a
   * "children" property which is an array of nested dropdown source items
   */
  collectKeyAndLabelFromSource(items) {
    items.forEach((item) => {
      if (item['children']) {
        this.collectKeyAndLabelFromSource(item['children']);
      }
      else {
        this.labelSet.add(item.label);
        this.keySet.add(item.key);
      }
    });
  }
  /* istanbul ignore next */
  /**
   * The below method is e2e-test covered in @see{module:vega-dropdown-items-dom-change-e2e}
   */
  clearDropdownCurrentData() {
    this.keySet.clear();
    this.labelSet.clear();
  }
  /**
   * The function `notifyTemplateItemsChange` notifies changes to dropdown items within a container element.
   */
  notifyTemplateItemsChange() {
    const container = this.renderer.getDropdownContentBoxRef() || this.host;
    ChangeManager.notify(DomNodeSubjectFactory.getSubject(this.host, VegaInternalDropdownTemplateItemsChange), container.querySelectorAll('vega-dropdown-item'));
  }
}
__decorate([
  MapToComponentField()
], VegaDropdownChildrenController.prototype, "host", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownChildrenController.prototype, "source", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownChildrenController.prototype, "sourceController", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownChildrenController.prototype, "renderModeController", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownChildrenController.prototype, "listRenderer", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownChildrenController.prototype, "renderer", void 0);
__decorate([
  MapToComponentField()
], VegaDropdownChildrenController.prototype, "selectedController", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaDropdownChildrenController.prototype, "mutationObserver", void 0);
__decorate([
  MapToComponentMethod('disconnectedCallback')
], VegaDropdownChildrenController.prototype, "disconnectedCallback", null);
__decorate([
  MapToComponentMethod('componentWillLoad')
], VegaDropdownChildrenController.prototype, "componentWillLoad", null);
__decorate([
  MapToComponentMethod('componentDidLoad')
], VegaDropdownChildrenController.prototype, "componentDidLoad", null);
__decorate([
  MapToComponentMethod('watchSource')
], VegaDropdownChildrenController.prototype, "watchSource", null);
