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, methodPlaceholder, VegaSlimmer, } from 'vega-slimmer/core';
import { MutationObserverSlimmer } from '../../../../../helpers/slimmers/mutation-observer/mutation-observer-slimmer';
import { TagNameAndAttributeMutationFilter } from '../../../../../helpers/slimmers/mutation-observer/mutation-observer-filters';
import { isArrayEqual } from '../../../../../utils/array';
/**
 * Observer child items change to update value.
 */
export class VegaSelectionChipGroupItemsController extends VegaSlimmer {
  constructor() {
    super(...arguments);
    this.mutationObserver = new MutationObserverSlimmer({
      // eslint-disable-next-line jsdoc/require-jsdoc
      target: () => this.host,
      options: {
        childList: true,
        subtree: true,
        attributes: true,
        attributeFilter: ['checked'],
      },
      mutationFilter: TagNameAndAttributeMutationFilter('VEGA-SELECTION-CHIP'),
      /*
       * The below method is e2e-test covered in
       * @see{module:vega-selection-chip-group-radio-slot-change-e2e}
       * @see{module:vega-selection-chip-group-checkbox-slot-change-e2e}
       */
      // eslint-disable-next-line jsdoc/require-jsdoc
      callback: this.syncChipArrayAndValue.bind(this),
    });
    this.selectionChipArray = [];
  }
  /**
   * Component lifecycle - [disconnectedCallback]
   */
  disconnectedCallback() {
    methodPlaceholder();
  }
  /**
   * Component lifecycle - [componentWillLoad]
   */
  componentWillLoad() {
    if (!this.value || this.value.length === 0) {
      this.syncChipArrayAndValue();
    }
  }
  /**
   * Component lifecycle - [componentDidLoad]
   */
  componentDidLoad() {
    methodPlaceholder();
  }
  /**
   * watchSelectType
   */
  watchSelectType() {
    this.syncChipArrayAndValue();
  }
  /**
   * The function returns current chip items array.
   *
   * @returns {HTMLVegaSelectionChipElement[]} - current chip items.
   */
  getSelectionChipArray() {
    return this.selectionChipArray;
  }
  /**
   * Synchronizes the selection chip array and the selected value based on the select type.
   *
   * @param {MutationRecord[]} mutations - Mutations record
   */
  syncChipArrayAndValue(mutations) {
    this.selectionChipArray = Array.from(this.host.querySelectorAll('vega-selection-chip'));
    this.selectType === 'checkbox'
      ? this.setValueFromCheckboxItems()
      : this.setValueFromRadioItems(mutations);
  }
  /**
   * Sets the value of an element based on the checked items in a selection chip array.
   */
  setValueFromCheckboxItems() {
    const currentValue = this.selectionChipArray
      .filter((chip) => chip.checked)
      .map((chip) => chip.value);
    // Should skip update the value while same items with different order are in the two value arrays.
    // ticket: https://gethired.atlassian.net/browse/VD-4534
    if (!isArrayEqual(this.value, currentValue, true)) {
      this.valueController.setValue(currentValue);
    }
  }
  /**
   * Sets the value of a radio item based on the checked status of the items.
   *
   * @param {MutationRecord[]} mutations - Mutations record
   */
  setValueFromRadioItems(mutations) {
    const mutation = this.findAttributeMutation(mutations);
    if (mutation) {
      const chip = this.getCurrentChip(mutation);
      if (chip && chip.checked) {
        this.valueController.setValue(chip.value);
      }
    }
    else {
      const chip = this.getFirstCheckedChip();
      this.valueController.setValue(chip ? chip.value : '');
    }
  }
  /**
   * Find the changed attribute mutation record.
   *
   * @param {MutationRecord[]} mutations - Mutations record
   * @returns {Nullable<MutationRecord>} - Changed attribute mutation record..
   */
  findAttributeMutation(mutations) {
    return mutations && mutations.find((mutation) => mutation.attributeName);
  }
  /**
   * Get the current checked chip element from mutation.
   *
   * @param {MutationRecord} mutation - mutation.
   * @returns {Nullable<HTMLVegaSelectionChipElement>} The current checked chip.
   */
  getCurrentChip(mutation) {
    if (mutation &&
      mutation.target.tagName === 'VEGA-SELECTION-CHIP' &&
      mutation.attributeName === 'checked') {
      return mutation.target;
    }
  }
  /**
   * Get the first checked chip element from an array of selection chips.
   *
   * @returns {Nullable<HTMLVegaSelectionChipElement>} The first checked chip.
   */
  getFirstCheckedChip() {
    return this.selectionChipArray.find((chip) => chip.checked);
  }
}
__decorate([
  MapToComponentField()
], VegaSelectionChipGroupItemsController.prototype, "host", void 0);
__decorate([
  MapToComponentField()
], VegaSelectionChipGroupItemsController.prototype, "selectType", void 0);
__decorate([
  MapToComponentField()
], VegaSelectionChipGroupItemsController.prototype, "valueController", void 0);
__decorate([
  MapToComponentField()
], VegaSelectionChipGroupItemsController.prototype, "value", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaSelectionChipGroupItemsController.prototype, "mutationObserver", void 0);
__decorate([
  MapToComponentMethod('disconnectedCallback')
], VegaSelectionChipGroupItemsController.prototype, "disconnectedCallback", null);
__decorate([
  MapToComponentMethod('componentWillLoad')
], VegaSelectionChipGroupItemsController.prototype, "componentWillLoad", null);
__decorate([
  MapToComponentMethod('componentDidLoad')
], VegaSelectionChipGroupItemsController.prototype, "componentDidLoad", null);
__decorate([
  MapToComponentMethod('watchSelectType')
], VegaSelectionChipGroupItemsController.prototype, "watchSelectType", null);
