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 { ValuePaginator } from '../../../../../helpers/paginator/value-paginator';
import { PageResizeObserverSlimmer } from '../../../../../helpers/slimmers/page-resize-observer-slimmer';
import { MapToComponentField, MapToComponentMethod } from 'vega-slimmer/core';
import { debounce } from '../../../../../utils/timer';
/** The `VegaTabGroupPagesController` class is responsible for managing the tab pages and their widths in a tab group component. */
export class VegaTabGroupPagesController extends PageResizeObserverSlimmer {
  /*
   * The below method is e2e-test covered in
   *
   * @see{module:vega-tab-group-with-screen-size-change}
   */
  /**
   * The constructor initializes a callback function and a target element.
   */
  constructor() {
    /* eslint-disable jsdoc/require-jsdoc*/
    super({
      callback: /* istanbul ignore next */ () => {
        this.initTabPagesWithDebounce();
      },
      target: /* istanbul ignore next */ () => this.host,
      shouldTrigger: /* istanbul ignore next */ () => {
        return !this.sliderStateController.isAnimationInProgress();
      },
    });
    this.TAB_SIDE_BUTTON_WIDTH = 37;
    /* The space of left button and first tab, right button hasn't space */
    this.TAB_SIDE_BUTTON_AND_CONTENT_SPACE = 8;
    this.valuePaginator = new ValuePaginator();
    this.initTabPagesWithDebounce = debounce(this.initTabPages, 80, this);
    /*
     * The below method is e2e-test covered in
     * @see{module:vega-tab-group-with-right-button}
     */
    /* istanbul ignore next */
    /**
     * 1.To calculate the visual width of the tab, you need to subtract the space occupied by the left and right buttons
     * 2.If the current page is greater than 0, show the left button
     * 3.If all tab widths of the current page and subsequent pages are larger than the visible width, display the right button.
     *
     * @param {number} startIndex start index
     * @param {values} values number array
     * @returns {number} the tab container width
     */
    this.getTabContainerSpace = (startIndex, values) => {
      const primaryMargin = 48;
      const groupWidth = this.host.getBoundingClientRect().width;
      let tabGroupContainerWidth = this.variant === 'secondary' ? groupWidth : groupWidth - primaryMargin;
      if (this.overflow === 'menu') {
        if (startIndex > 0) {
          tabGroupContainerWidth -= this.TAB_SIDE_BUTTON_WIDTH + this.TAB_SIDE_BUTTON_AND_CONTENT_SPACE;
        }
        const showRightButton = values.length > 0 &&
          values.slice(startIndex).reduce((prev, current) => prev + current) >
            tabGroupContainerWidth &&
          tabGroupContainerWidth > 0;
        if (showRightButton) {
          tabGroupContainerWidth -= this.TAB_SIDE_BUTTON_WIDTH;
        }
      }
      return tabGroupContainerWidth;
    };
    /**
     * The `emptySourceAndHiddenDropdown` method is responsible for hiding any dropdown elements that have an empty source.
     */
    this.emptySourceAndHiddenDropdown = () => {
      const dropdownElements = Array.from(this.host.shadowRoot.querySelectorAll('vega-dropdown'));
      dropdownElements.forEach(async (element) => {
        if (element.source.length === 0) {
          await element.hide();
        }
      });
    };
    /* eslint-enable jsdoc/require-jsdoc*/
  }
  /**
   * initial the tab pages when component call the componentDidLoad method
   */
  componentDidLoad() {
    this.initTabPages();
  }
  /**
   * initial the tab pages when component call the componentDidRender method
   */
  componentDidRender() {
    this.initTabsWidthArray();
    this.emptySourceAndHiddenDropdown();
  }
  /* istanbul ignore next*/
  /**
   * initial the tab pages when component call the watchGapChange method
   *
   * {@link VegaTabGroup#watchGapChange}
   */
  handleGapChange() {
    this.initTabPages();
  }
  /* istanbul ignore next*/
  /**
   * initial the tab pages when component call the watchTabWidthArrayChange method
   *
   * {@link VegaTabGroup#watchTabWidthArrayChange}
   */
  handleTabWidthArrayChange() {
    if (this.tabWidthArray.length > 0) {
      this.initTabPages();
    }
  }
  /*
   * The below method is e2e-test covered in
   * @see{module:vega-tab-group-watch-tab-items-on-change}
   */
  /* istanbul ignore next */
  /**
   * On tab items value change, initialize tab pages
   */
  handleTabItemsChange() {
    this.initTabPagesWithDebounce();
  }
  /**
   * The function sets the tab items for a tab configuration.
   *
   * @param {TabConfig[]} value - The value parameter is an array of TabConfig objects.
   */
  setTabItems(value) {
    this.tabItems = value;
  }
  /**
   * The function sets the tab width array to the given value.
   *
   * @param {number[]} value - The value parameter is an array of numbers.
   */
  setTabWidthArray(value) {
    this.tabWidthArray = value;
  }
  /*
   * The below method is e2e-test covered in
   * @see {module:vega-tab-group-with-gap-change}
   */
  /* istanbul ignore next */
  /**
   * initial the tab pages
   */
  initTabPages() {
    if (this.tabItems) {
      if (this.overflow === 'scroll') {
        this.tabPages = [[...this.tabItems]];
      }
      else {
        this.tabPages = this.valuePaginator.paginate(this.tabItems, (_input, index) => this.tabWidthArray[index] > 0
          ? this.tabWidthArray[index] + Number(this.formatAndValidGap(this.gap))
          : this.tabWidthArray[index], this.getTabContainerSpace);
      }
    }
  }
  /*
   * The below method is e2e-test covered in
   * @see{module:vega-tab-group-with-right-button}
   */
  /* istanbul ignore next */
  /**
   * get the gap size from token
   *
   * @param {SpacingTokenType} gap gap token string
   * @returns {string} the size number
   */
  formatAndValidGap(gap) {
    return gap.replace('size-', '');
  }
  /*
   * The below method is e2e-test covered in
   * @see {module:vega-tab-group-with-right-button}
   */
  /* istanbul ignore next */
  /**
   * 1.record the width of tab.
   * 2.the width of every tab is zero if the tab group component embedded in modal, so need recalculate the width of tab.
   */
  initTabsWidthArray() {
    if (this.tabWidthArray.length === 0 ||
      this.tabWidthArray.some((tabWidth) => tabWidth === 0)) {
      const newTabWidthArray = [];
      this.tabItems.forEach((item) => {
        const tabItem = this.host.shadowRoot.querySelector(`.vega-tab[data-target='${item.dataTarget}']`);
        if (tabItem) {
          const tabWidth = tabItem.getBoundingClientRect().width;
          newTabWidthArray.push(tabWidth);
        }
      });
      if (newTabWidthArray.length > 0 && !newTabWidthArray.some((tabWidth) => tabWidth === 0)) {
        this.tabWidthArray = [...newTabWidthArray];
      }
    }
  }
}
__decorate([
  MapToComponentField()
], VegaTabGroupPagesController.prototype, "host", void 0);
__decorate([
  MapToComponentField()
], VegaTabGroupPagesController.prototype, "gap", void 0);
__decorate([
  MapToComponentField({ writable: true })
], VegaTabGroupPagesController.prototype, "tabPages", void 0);
__decorate([
  MapToComponentField({ writable: true })
], VegaTabGroupPagesController.prototype, "tabWidthArray", void 0);
__decorate([
  MapToComponentField({ writable: true })
], VegaTabGroupPagesController.prototype, "tabItems", void 0);
__decorate([
  MapToComponentField()
], VegaTabGroupPagesController.prototype, "variant", void 0);
__decorate([
  MapToComponentField()
], VegaTabGroupPagesController.prototype, "overflow", void 0);
__decorate([
  MapToComponentField({ componentFieldName: 'vegaTabGroupSliderStateController' })
], VegaTabGroupPagesController.prototype, "sliderStateController", void 0);
__decorate([
  MapToComponentMethod('componentDidLoad')
], VegaTabGroupPagesController.prototype, "componentDidLoad", null);
__decorate([
  MapToComponentMethod('componentDidRender')
], VegaTabGroupPagesController.prototype, "componentDidRender", null);
__decorate([
  MapToComponentMethod('watchGapChange')
], VegaTabGroupPagesController.prototype, "handleGapChange", null);
__decorate([
  MapToComponentMethod('watchTabWidthArrayChange')
], VegaTabGroupPagesController.prototype, "handleTabWidthArrayChange", null);
__decorate([
  MapToComponentMethod('watchTabItemsChange')
], VegaTabGroupPagesController.prototype, "handleTabItemsChange", null);
