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 { Component, Host, h, Prop, Element, Event, Watch, State } from '@stencil/core';
import { sanitizeVegaComponent } from '../../utils/component';
import { VegaPaginationCurrentPageLabel } from './internal/vega-pagination-current-page-label';
import { VegaPaginationGoTo } from './internal/vega-pagination-go-to';
import { VegaPaginationPageSizeSelector } from './internal/vega-pagination-page-size-selector';
import { VegaPaginationPageSelector } from './internal/vega-pagination-page-selector';
import { includesPageSize, hasAllOption, resolvePageSizeValue } from './utils/page-size-option-utils';
import { PAGE_SIZE_ALL } from './constants/page-size';
import { ChildNodesEventPreventSlimmer } from '../../helpers/event-manager/slimmers/child-nodes-event-prevent-slimmer';
import { VegaChange, VegaFormSubmit, VegaPageSizeChange, } from '../../helpers/event-manager/event-id/vega-event-id';
import { createEventEmitSlimmer, } from '../../helpers/event-manager/slimmers/event-emit-slimmer';
import { InjectVegaGlobalSlimmer, InjectVegaSlimmer, methodPlaceholder, } from 'vega-slimmer/core';
import { VegaComponentUsageRuntimeMetricsSlimmer } from '../../helpers/slimmers/component-usage-runtime-metrics';
import { TranslationSlimmer } from '../../helpers/slimmers/translation';
import ResponsiveFormatFacade from '../../helpers/formatter/responsive-map-formatter/responsive-format-facade';
import { getCurrentBreakpoint } from '../../utils/breakpoints';
import { PageResizeObserverSlimmer } from '../../helpers/slimmers/page-resize-observer-slimmer';
import { VegaPaginationPageSizeObserverController } from './slimmers/controllers/vega-pagination-page-size-observer-controller';
import { VegaPaginationCurrentPageObserverController } from './slimmers/controllers/vega-pagination-current-page-observer-controller';
import { FeatureFlag } from '../../helpers/feature-control/feature-flag-controller';
import { VegaPaginationLayoutController } from './slimmers/controllers/vega-pagination-layout-controller';
/**
 * @vegaVersion 1.3.0
 */
export class VegaPagination {
  constructor() {
    this.globalSlimmers = {};
    this.translationSlimmer = new TranslationSlimmer();
    this.childEventPrevent = new ChildNodesEventPreventSlimmer([VegaFormSubmit], () => this.host);
    this.childValueChangePrevent = new ChildNodesEventPreventSlimmer([VegaChange], () => this.host, true);
    this.vegaChangeEventEmitter = createEventEmitSlimmer(VegaPagination, VegaChange);
    this.vegaPageSizeChangeEventEmitter = createEventEmitSlimmer(VegaPagination, VegaPageSizeChange);
    this.vegaComponentUsageRuntimeMetricsSlimmer = new VegaComponentUsageRuntimeMetricsSlimmer();
    this.vegaPaginationPageSizeObserverController = new VegaPaginationPageSizeObserverController();
    this.vegaPaginationCurrentPageObserverController = new VegaPaginationCurrentPageObserverController();
    this.breakpointPageResizeObserverSlimmer = new PageResizeObserverSlimmer();
    this.vegaPaginationLayoutController = new VegaPaginationLayoutController();
    this.vegaPaginationItemTypes = [
      'currentPageLabel',
      'pageSizeSelector',
      'pageSelector',
      'goTo',
      'pageSelectorMobile',
      'pageSizeSelectorMobile',
      'pageSelectorMobile_goTo',
      'pageSizeSelectorMobile_currentPageLabel',
    ];
    this.currentBreakpoint = getCurrentBreakpoint();
    /**
     * Total number of pages.
     */
    this.pageCount = 0;
    /** Tracks whether "All" was explicitly selected or initialized. */
    this.isAllActive = false;
    /**
     * Specifies the current page number for
     *    the pagination component.
     *
     * @vegaVersion 1.3.0
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.current = 1;
    /**
     * Specifies the total number of data items for the pagination component.
     *
     * @vegaVersion 1.3.0
     */
    this.total = 0;
    /**
     * Specifies the number of data items to be displayed per page in
     *    the pagination component.
     *
     * @vegaVersion 1.3.0
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.pageSize = 10;
    /**
     * Specifies the extensions associated with the pagination items
     *    in the pagination component.
     *
     * It refers to additional elements or components that can be added to
     *    enhance the functionality or appearance of each pagination item.
     *
     * @VegaWarning - Note: The default value is controlled by feature flag `VEGA_PAGINATION.ENABLE_EXTENSIONS_RESPONSIVE_DEFAULT_VALUE`, which is disabled by default.
     *              - To enable the new responsive default value `{
              default: [['pageSizeSelectorMobile_currentPageLabel'], ['pageSelectorMobile_goTo']],
                M: [['pageSelector']],
                    }`, please enable the feature flag.
     * @vegaVersion 1.25.0
     * @defaultValue [['pageSelector']]
     */
    this.extensions = FeatureFlag.isEnabled('VEGA_PAGINATION.ENABLE_EXTENSIONS_RESPONSIVE_DEFAULT_VALUE')
      ? {
        default: [['pageSizeSelectorMobile_currentPageLabel'], ['pageSelectorMobile_goTo']],
        M: [['pageSelector']],
      }
      : [['pageSelector']];
    /**
     * Specifies the layout of the elements.
     *
     * It determines how the pagination elements are arranged, with options such as 'horizontal' for a horizontal layout or other defined layouts.
     *
     * @vegaVersion 2.42.0
     */
    this.layout = 'horizontal';
    /**
     * Specifies the options available for the page size selector
     *    in the pagination component.
     *
     * Each option can be a number or an object with `value` and `label`.
     * Use `{ value: -1, label: 'All' }` to show all items on a single page.
     *
     * @vegaVersion 1.25.0
     */
    /* eslint-disable-next-line @stencil/strict-mutable */
    this.pageSizeSelectorOptions = [10, 20, 50, 100];
    this.renderPaginationItemsWrapper = (extensionArr) => {
      return (h("vega-flex", { gap: { default: 'size-4', M: 'size-24' }, flexWrap: "wrap", alignItems: "center", justifyContent: "center", key: this.generateWrapperKey(extensionArr) }, extensionArr.map((item) => {
        return h("div", { key: item }, this.renderPaginationItem(item));
      })));
    };
    this.renderPaginationItem = (item) => {
      switch (item) {
        case 'currentPageLabel':
          return (h(VegaPaginationCurrentPageLabel, { total: this.total, current: this.current, pageSize: this.pageSize, translationSlimmer: this.translationSlimmer }));
        case 'pageSizeSelector': {
          const pageSizeSelectorOptions = this.isAllActive || includesPageSize(this.pageSizeSelectorOptions, this.pageSize)
            ? this.pageSizeSelectorOptions
            : [...this.pageSizeSelectorOptions, this.pageSize];
          return (h(VegaPaginationPageSizeSelector, { pageSize: this.pageSize, pageSizeSelectorOptions: pageSizeSelectorOptions, dropdownProps: this.dropdownProps, onChange: this.onPageSizeSelectorChange, translationSlimmer: this.translationSlimmer, isAllActive: this.isAllActive }));
        }
        case 'pageSelector':
          return (h(VegaPaginationPageSelector, { current: this.current, total: this.total, onChange: this.onPageSelectorChange, pageCount: this.pageCount }));
        case 'goTo':
          return (h(VegaPaginationGoTo, { onChange: this.handlePaginationGoToChange, pageCount: this.pageCount, translationSlimmer: this.translationSlimmer }));
        case 'pageSelectorMobile':
        case 'pageSelectorMobile_goTo':
          return (h("vega-pagination-page-selector-mobile", { type: item, pageCount: this.pageCount, current: this.current, total: this.total }));
        case 'pageSizeSelectorMobile':
        case 'pageSizeSelectorMobile_currentPageLabel':
          return (h("vega-pagination-page-size-selector-mobile", { type: item, pageSize: this.pageSize, current: this.current, total: this.total, pageSizeSelectorOptions: this.pageSizeSelectorOptions, dropdownProps: this.dropdownProps, isAllActive: this.isAllActive }));
      }
    };
    this.handlePaginationGoToChange = (page) => {
      this.current = page;
    };
    this.onPageSizeSelectorChange = (pageSize) => {
      this.isAllActive = pageSize === PAGE_SIZE_ALL;
      this.pageSize = resolvePageSizeValue(pageSize, this.total);
    };
    this.calculatePages = () => {
      if (!this.total) {
        return 0;
      }
      return Math.floor((this.total - 1) / this.pageSize) + 1;
    };
    this.onPageSelectorChange = (page) => {
      this.current = page;
    };
    this.removeDuplicateItems = (extensions) => {
      const items = [...this.vegaPaginationItemTypes];
      const extensionsClone = [...extensions];
      return extensionsClone
        .map((extension) => {
        return extension.filter((item, itemIndex) => {
          const index = items.indexOf(item);
          if (index >= 0) {
            items.splice(index, 1);
            return true;
          }
          else {
            extension.splice(itemIndex, 1);
            return false;
          }
        });
      })
        .filter((arr) => arr.length > 0);
    };
    this.generateWrapperKey = (extensionArr) => {
      return extensionArr
        .map(String)
        .reduce((pre, cur) => `${pre}-${cur}`);
    };
    this.currentValueGuard = () => {
      if (this.pageCount === 0) {
        this.current = 1;
      }
      else if (this.current > this.pageCount) {
        this.current = this.pageCount;
      }
    };
  }
  /*
   * The next line is covered in e2e-test
   * @see{should-render-layout-properly-when-set-responsive-prop-layout}
   */
  /* istanbul ignore next */
  watchCurrentBreakpoint() {
    methodPlaceholder();
  }
  watchPageCount() {
    this.currentValueGuard();
  }
  watchCurrent() {
    this.currentValueGuard();
    this.vegaChangeEventEmitter.emit(this.current);
  }
  watchTotal(newTotal) {
    if (this.isAllActive) {
      this.pageSize = newTotal;
    }
    this.pageCount = this.calculatePages();
  }
  watchPageSize() {
    this.vegaPageSizeChangeEventEmitter.emit(this.pageSize);
    this.pageCount = this.calculatePages();
  }
  watchLayout() {
    methodPlaceholder();
  }
  componentWillLoad() {
    this.isAllActive =
      hasAllOption(this.pageSizeSelectorOptions) &&
        this.pageSize === this.total &&
        !includesPageSize(this.pageSizeSelectorOptions, this.pageSize);
    this.pageCount = this.calculatePages();
    this.currentValueGuard();
    if (!this.isAllActive && !includesPageSize(this.pageSizeSelectorOptions, this.pageSize)) {
      this.pageSizeSelectorOptions = [...this.pageSizeSelectorOptions, this.pageSize];
    }
  }
  render() {
    const currentExtensions = ResponsiveFormatFacade.formatCustom(this.extensions);
    return sanitizeVegaComponent(h(Host, null, this.removeDuplicateItems(currentExtensions).map(this.renderPaginationItemsWrapper)), this.host);
  }
  static get is() { return "vega-pagination"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() { return {
    "$": ["vega-pagination.scss"]
  }; }
  static get styleUrls() { return {
    "$": ["vega-pagination.css"]
  }; }
  static get properties() { return {
    "current": {
      "type": "number",
      "mutable": true,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.3.0"
          }],
        "text": "Specifies the current page number for\n   the pagination component."
      },
      "attribute": "current",
      "reflect": true,
      "defaultValue": "1"
    },
    "total": {
      "type": "number",
      "mutable": false,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.3.0"
          }],
        "text": "Specifies the total number of data items for the pagination component."
      },
      "attribute": "total",
      "reflect": false,
      "defaultValue": "0"
    },
    "pageSize": {
      "type": "number",
      "mutable": true,
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.3.0"
          }],
        "text": "Specifies the number of data items to be displayed per page in\n   the pagination component."
      },
      "attribute": "page-size",
      "reflect": false,
      "defaultValue": "10"
    },
    "extensions": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "ResponsiveType<VegaPaginationItemType[][]>",
        "resolved": "VegaPaginationItemType[][] | { S?: VegaPaginationItemType[][]; M?: VegaPaginationItemType[][]; L?: VegaPaginationItemType[][]; XL?: VegaPaginationItemType[][]; default?: VegaPaginationItemType[][]; }",
        "references": {
          "ResponsiveType": {
            "location": "import",
            "path": "../../types/ui.type"
          },
          "VegaPaginationItemType": {
            "location": "import",
            "path": "./types"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "VegaWarning",
            "text": "- Note: The default value is controlled by feature flag `VEGA_PAGINATION.ENABLE_EXTENSIONS_RESPONSIVE_DEFAULT_VALUE`, which is disabled by default. \n- To enable the new responsive default value `{\ndefault: [['pageSizeSelectorMobile_currentPageLabel'], ['pageSelectorMobile_goTo']],\nM: [['pageSelector']],\n}`, please enable the feature flag."
          }, {
            "name": "vegaVersion",
            "text": "1.25.0"
          }, {
            "name": "defaultValue",
            "text": "[['pageSelector']]"
          }],
        "text": "Specifies the extensions associated with the pagination items\n   in the pagination component.\n\nIt refers to additional elements or components that can be added to\n   enhance the functionality or appearance of each pagination item."
      },
      "defaultValue": "FeatureFlag.isEnabled(\n\t\t'VEGA_PAGINATION.ENABLE_EXTENSIONS_RESPONSIVE_DEFAULT_VALUE',\n\t)\n\t\t? {\n\t\t\t\tdefault: [['pageSizeSelectorMobile_currentPageLabel'], ['pageSelectorMobile_goTo']],\n\t\t\t\tM: [['pageSelector']],\n\t\t  }\n\t\t: [['pageSelector']]"
    },
    "layout": {
      "type": "string",
      "mutable": false,
      "complexType": {
        "original": "ResponsiveType<VegaPaginationLayoutType>",
        "resolved": "\"horizontal\" | \"vertical\" | { S?: VegaPaginationLayoutType; M?: VegaPaginationLayoutType; L?: VegaPaginationLayoutType; XL?: VegaPaginationLayoutType; default?: VegaPaginationLayoutType; }",
        "references": {
          "ResponsiveType": {
            "location": "import",
            "path": "../../types/ui.type"
          },
          "VegaPaginationLayoutType": {
            "location": "import",
            "path": "./types"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "2.42.0"
          }],
        "text": "Specifies the layout of the elements.\n\nIt determines how the pagination elements are arranged, with options such as 'horizontal' for a horizontal layout or other defined layouts."
      },
      "attribute": "layout",
      "reflect": false,
      "defaultValue": "'horizontal'"
    },
    "pageSizeSelectorOptions": {
      "type": "unknown",
      "mutable": true,
      "complexType": {
        "original": "VegaPaginationPageSizeOption[]",
        "resolved": "VegaPaginationPageSizeOption[]",
        "references": {
          "VegaPaginationPageSizeOption": {
            "location": "import",
            "path": "./types"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.25.0"
          }],
        "text": "Specifies the options available for the page size selector\n   in the pagination component.\n\nEach option can be a number or an object with `value` and `label`.\nUse `{ value: -1, label: 'All' }` to show all items on a single page."
      },
      "defaultValue": "[10, 20, 50, 100]"
    },
    "dropdownProps": {
      "type": "unknown",
      "mutable": false,
      "complexType": {
        "original": "DropdownPropsForPagination",
        "resolved": "{ isScreenPosition?: boolean; }",
        "references": {
          "DropdownPropsForPagination": {
            "location": "import",
            "path": "./types"
          }
        }
      },
      "required": false,
      "optional": false,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "2.36.0"
          }],
        "text": "Specifies the properties of the `vega-dropdown` component\n   used to configure the dropdown for the\n   page size selector in pagination."
      }
    }
  }; }
  static get states() { return {
    "currentBreakpoint": {},
    "pageCount": {},
    "isAllActive": {}
  }; }
  static get events() { return [{
      "method": "vegaChange",
      "name": "vegaChange",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.3.0"
          }],
        "text": "An event emitter notifying the current page change."
      },
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      }
    }, {
      "method": "change",
      "name": "change",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [{
            "name": "eventSemantics",
            "text": "namespace:native"
          }, {
            "name": "vegaVersion",
            "text": "2.0.0"
          }],
        "text": "An event emitter notifying the current page change."
      },
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      }
    }, {
      "method": "vegaPageSizeChange",
      "name": "vegaPageSizeChange",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [{
            "name": "vegaVersion",
            "text": "1.25.0"
          }],
        "text": "An event emitter notifying a change in the number of\n   data items displayed per page."
      },
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      }
    }, {
      "method": "pageSizeChange",
      "name": "pageSizeChange",
      "bubbles": true,
      "cancelable": true,
      "composed": true,
      "docs": {
        "tags": [{
            "name": "eventSemantics",
            "text": "namespace:native"
          }, {
            "name": "vegaVersion",
            "text": "2.0.0"
          }],
        "text": "An event emitter notifying a change in the number of\n   data items displayed per page."
      },
      "complexType": {
        "original": "number",
        "resolved": "number",
        "references": {}
      }
    }]; }
  static get elementRef() { return "host"; }
  static get watchers() { return [{
      "propName": "currentBreakpoint",
      "methodName": "watchCurrentBreakpoint"
    }, {
      "propName": "pageCount",
      "methodName": "watchPageCount"
    }, {
      "propName": "current",
      "methodName": "watchCurrent"
    }, {
      "propName": "total",
      "methodName": "watchTotal"
    }, {
      "propName": "pageSize",
      "methodName": "watchPageSize"
    }, {
      "propName": "layout",
      "methodName": "watchLayout"
    }]; }
}
__decorate([
  InjectVegaGlobalSlimmer()
], VegaPagination.prototype, "globalSlimmers", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "translationSlimmer", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "childEventPrevent", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "childValueChangePrevent", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "vegaChangeEventEmitter", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "vegaPageSizeChangeEventEmitter", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "vegaComponentUsageRuntimeMetricsSlimmer", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "vegaPaginationPageSizeObserverController", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "vegaPaginationCurrentPageObserverController", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "breakpointPageResizeObserverSlimmer", void 0);
__decorate([
  InjectVegaSlimmer()
], VegaPagination.prototype, "vegaPaginationLayoutController", void 0);
