/**
 * Copyright IBM Corp. 2026
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import "../../globals/settings.js";
import { carbonElement } from "../../globals/decorators/carbon-element.js";
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.126.0/helpers/decorate.js";
import iconLoader from "../../globals/internal/icon-loader.js";
import FocusMixin from "../../globals/mixins/focus.js";
import HostListener from "../../globals/decorators/host-listener.js";
import HostListenerMixin from "../../globals/mixins/host-listener.js";
import "../button/index.js";
import "./defs.js";
import pagination_default$1 from "./pagination.scss.js";
import { LitElement, html } from "lit";
import { property, query } from "lit/decorators.js";
import CaretLeft16 from "@carbon/icons/es/caret--left/16.js";
import CaretRight16 from "@carbon/icons/es/caret--right/16.js";
//#region src/components/pagination/pagination.ts
/**
* Pagination UI.
*
* @element cds-pagination
* @slot page-sizes-select - Where to put in the `<page-sizes-select>`.
* @fires cds-pagination-changed-current - The custom event fired after the current page is changed from `<cds-pages-select>`.
* @fires cds-page-sizes-select-changed - The custom event fired after the number of rows per page is changed from `<cds-page-sizes-select>`.
*/
let CDSPagination = class CDSPagination extends FocusMixin(HostListenerMixin(LitElement)) {
	constructor(..._args) {
		super(..._args);
		this.backwardText = "Previous page";
		this.backwardTextTooltipPosition = "top";
		this.page = 1;
		this.formatLabelText = ({ count }) => `Page of ${count} page${count <= 1 ? "" : "s"}`;
		this.formatStatusWithDeterminateTotal = ({ start, end, count }) => `${start}–${end} of ${count} item${count <= 1 ? "" : "s"}`;
		this.formatStatusWithIndeterminateTotal = ({ start, end, count }) => end == null ? `Item ${start}–` : `${start}–${end} item${count <= 1 ? "" : "s"}`;
		this.formatSupplementalText = ({ count }) => this.pagesUnknown || !this.totalItems ? `page` : `of ${count} page${count <= 1 ? "" : "s"}`;
		this.itemsPerPageText = "";
		this.disabled = false;
		this.forwardText = "Next page";
		this.forwardTextTooltipPosition = "top";
		this.pageInputDisabled = false;
		this.pageSize = 10;
		this.pagesUnknown = false;
		this.size = "md";
		this.start = 0;
		this.totalPages = 1;
	}
	_handleSlotChange({ target }) {
		target.assignedNodes().filter((node) => node.nodeType !== Node.TEXT_NODE || node.textContent.trim()).forEach((item) => {
			this._pageSizeSelect.appendChild(item);
		});
	}
	/**
	* @returns Page status text.
	*/
	_renderStatusText() {
		const { start, pageSize, totalItems, pagesUnknown, formatStatusWithDeterminateTotal, formatStatusWithIndeterminateTotal } = this;
		const min = totalItems === 0 ? 0 : start + 1;
		if (pagesUnknown || totalItems == null) {
			if (totalItems === 0) return formatStatusWithDeterminateTotal({
				start: 0,
				end: 0,
				count: 0
			});
			const end = start + pageSize;
			return formatStatusWithIndeterminateTotal({
				start: min,
				end,
				count: Math.max(0, end - start)
			});
		}
		return formatStatusWithDeterminateTotal({
			start: min,
			end: Math.min(start + pageSize, totalItems),
			count: totalItems
		});
	}
	/**
	* Calculates the start value based on `page`, `pageSize`, and `totalItems`
	*/
	_calculateStart(page, pageSize, totalItems, pagesUnknown) {
		if (!pagesUnknown && totalItems === 0) return 0;
		const safePageSize = pageSize > 0 ? pageSize : 1;
		const calculatedStart = (Math.max(1, page) - 1) * safePageSize;
		if (!pagesUnknown && Number.isFinite(totalItems)) {
			const maxStart = (Math.ceil(totalItems / safePageSize) - 1) * safePageSize;
			return Math.max(0, Math.min(calculatedStart, maxStart));
		}
		return Math.max(0, calculatedStart);
	}
	/**
	* Handles user-initiated change in the row number the current page starts with.
	*
	* @param start The new current row number, index that starts with zero.
	*/
	_handleUserInitiatedChangeStart(start) {
		this.start = start;
		this.dispatchEvent(new CustomEvent(this.constructor.eventChangeCurrent, {
			bubbles: true,
			composed: true,
			detail: {
				page: this.page,
				pageSize: this.pageSize
			}
		}));
	}
	/**
	* Handles user-initiated change in the size of the page.
	*/
	_handleUserInitiatedPageSizeChange() {
		this.dispatchEvent(new CustomEvent(this.constructor.eventPageSizeChanged, {
			bubbles: true,
			composed: true,
			detail: {
				page: this.page,
				pageSize: this.pageSize
			}
		}));
	}
	/**
	* Handles `click` event on the previous button.
	*/
	_handleClickPrevButton() {
		const { start: oldStart, pageSize } = this;
		this.page--;
		const newStart = Math.max(oldStart - pageSize, 0);
		if (newStart !== oldStart) this._handleUserInitiatedChangeStart(newStart);
		if (this.page === 1) {
			const { selectorForwardButton } = this.constructor;
			(this.shadowRoot?.querySelector(`[button-class-name*=${selectorForwardButton}]`)).focus();
		}
	}
	/**
	* Handles `click` event on the next button.
	*/
	_handleClickNextButton() {
		const { start: oldStart, pageSize, totalItems, pagesUnknown } = this;
		this.page++;
		const newStart = oldStart + pageSize;
		if (newStart < (totalItems == null ? Infinity : totalItems) || pagesUnknown) this._handleUserInitiatedChangeStart(newStart);
		if (!pagesUnknown && this.page === this.totalPages) {
			const { selectorPreviousButton } = this.constructor;
			(this.shadowRoot?.querySelector(`[button-class-name*=${selectorPreviousButton}]`)).focus();
		}
	}
	/**
	* Handles user-initiated change in number of rows per page.
	*
	* @param event The event.
	*/
	_handleChangeSelector(event) {
		const { value } = event.detail;
		const { totalItems, pageSize, pagesUnknown } = this;
		if (event.composedPath()[0] === this._pageSizeSelect) {
			this.pageSize = parseInt(value);
			this.totalPages = pageSize > 0 ? Math.ceil(totalItems / pageSize) : totalItems;
			this.page = 1;
			this.start = 0;
			this._handleUserInitiatedPageSizeChange();
		} else {
			this.page = Number(value);
			const newStart = this._calculateStart(value, pageSize, totalItems, pagesUnknown);
			this._handleUserInitiatedChangeStart(newStart);
		}
	}
	updated(changedProperties) {
		const { pageSize, totalItems } = this;
		const { selectorPageSizesSelect, selectorPagesSelect } = this.constructor;
		if (changedProperties.has("pageSize")) {
			const pageSizeSelect = this.shadowRoot?.querySelector(selectorPageSizesSelect);
			if (pageSizeSelect) pageSizeSelect.value = String(pageSize ?? "");
		}
		if (changedProperties.has("pageSize") || changedProperties.has("start") || changedProperties.has("totalItems") || changedProperties.has("page")) {
			const computedTotalPages = pageSize > 0 ? Math.ceil((totalItems ?? 0) / pageSize) : totalItems ?? 0;
			if (this.totalPages !== computedTotalPages) this.updateComplete.then(() => {
				this.totalPages = computedTotalPages;
			});
			const totalPagesSafe = Math.max(1, computedTotalPages || 1);
			const requestedPage = Math.max(1, Math.floor(this.page || 1));
			const displayPage = Math.min(requestedPage, totalPagesSafe);
			const pagesSelect = this.shadowRoot?.querySelector(selectorPagesSelect);
			if (pagesSelect) pagesSelect.value = displayPage.toString();
		}
		if (changedProperties.has("page")) {
			this.start = this._calculateStart(this.page, this.pageSize, this.totalItems, this.pagesUnknown);
			const pagesSelect = this.shadowRoot?.querySelector(this.constructor.selectorPagesSelect);
			if (pagesSelect) pagesSelect.value = String(this.page);
		}
	}
	render() {
		const { page, disabled, forwardText, forwardTextTooltipPosition, backwardText, backwardTextTooltipPosition, itemsPerPageText, pageInputDisabled, pageSize, pageSizeInputDisabled, pagesUnknown, size, start, totalItems, totalPages, _handleClickPrevButton: handleClickPrevButton, _handleClickNextButton: handleClickNextButton, _handleSlotChange: handleSlotChange, formatLabelText, formatSupplementalText } = this;
		const { isLastPage = start + pageSize >= totalItems } = this;
		const prevButtonDisabled = disabled || start === 0;
		const nextButtonDisabled = disabled || !pagesUnknown && isLastPage;
		const prevButtonClassMap = {
			[`cds--btn`]: true,
			[`cds--btn--icon-only`]: true,
			[`cds--pagination__button`]: true,
			[`cds--pagination__button--backward`]: true,
			[`cds--pagination__button--no-index`]: prevButtonDisabled,
			[`cds--btn--${size}`]: true,
			[`cds--btn--ghost`]: true
		};
		const nextButtonClassMap = {
			[`cds--btn`]: true,
			[`cds--btn--icon-only`]: true,
			[`cds--pagination__button`]: true,
			[`cds--pagination__button--forward`]: true,
			[`cds--pagination__button--no-index`]: nextButtonDisabled,
			[`cds--btn--${size}`]: true,
			[`cds--btn--ghost`]: true
		};
		const prevButtonClasses = Object.entries(prevButtonClassMap).filter(([, value]) => value === true).map(([key]) => key).join(" ");
		const nextButtonClasses = Object.entries(nextButtonClassMap).filter(([, value]) => value === true).map(([key]) => key).join(" ");
		const totalPagesSafe = Number.isFinite(totalPages) && totalPages > 0 ? totalPages : Math.max(1, page || 1);
		return html`
      <div class="${"cds"}--pagination__left">
        <cds-select
          ?disabled=${disabled || pageSizeInputDisabled}
          id="page-size-select"
          left-select
          pagination
          size="${size}"
          inline
          value="${pageSize}"
          label-styles-disable>
          <div slot="label-text">
            ${itemsPerPageText && html`<span class="${"cds"}--pagination__text"
              >${itemsPerPageText}</span
            >`}
            <slot name="label-text"></slot>
          </div>
          <slot @slotchange=${handleSlotChange}></slot>
        </cds-select>
        <span
          class="${"cds"}--pagination__text ${"cds"}--pagination__items-count"
          >${this._renderStatusText()}</span
        >
      </div>
      <div class="${"cds"}--pagination__right">
        ${pagesUnknown || !totalItems ? html`
              <span
                class="${"cds"}--pagination__text ${"cds"}--pagination__page-text ${"cds"}--pagination__unknown-pages-text"
                >${formatSupplementalText({ count: totalPages })} ${page}</span
              >
            ` : html`
              <cds-select
                ?disabled=${disabled || pageInputDisabled}
                id="pages-select"
                pagination
                size="${size}"
                inline
                value="${page}"
                hide-label>
                <span slot="label-text">
                  ${formatLabelText({ count: totalPages })}
                </span>
                ${Array.from(new Array(totalPagesSafe)).map((_item, index) => html`
                    <cds-select-item
                      value="${index + 1}"
                      ?selected=${page === index + 1}>
                      ${index + 1}
                    </cds-select-item>
                  `)}
              </cds-select>
              <span class="${"cds"}--pagination__text"
                >${formatSupplementalText({ count: totalPages })}</span
              >
            `}

        <div class="${"cds"}--pagination__control-buttons">
          <cds-button
            tooltip-position=${backwardTextTooltipPosition}
            pagination
            size="${size}"
            ?disabled="${prevButtonDisabled}"
            button-class-name="${prevButtonClasses}"
            tooltip-text="${backwardText}"
            @click="${handleClickPrevButton}">
            ${iconLoader(CaretLeft16, { slot: "icon" })}
          </cds-button>
          <cds-button
            tooltip-position=${forwardTextTooltipPosition}
            pagination
            size="${size}"
            ?disabled="${nextButtonDisabled}"
            button-class-name="${nextButtonClasses}"
            tooltip-text="${forwardText}"
            @click="${handleClickNextButton}">
            ${iconLoader(CaretRight16, { slot: "icon" })}
          </cds-button>
        </div>
      </div>
    `;
	}
	/**
	* A selector that will return the select box for the current page.
	*/
	static get selectorPagesSelect() {
		return `cds-select#pages-select`;
	}
	/**
	* A selector that will return the select box for page sizes.
	*/
	static get selectorPageSizesSelect() {
		return `cds-select`;
	}
	/**
	* A selector that will return the previous button.
	*/
	static get selectorPreviousButton() {
		return `cds--pagination__button--backward`;
	}
	/**
	* A selector that will return the forward button.
	*/
	static get selectorForwardButton() {
		return `cds--pagination__button--forward`;
	}
	/**
	* The name of the custom event fired after the current row number is changed.
	*/
	static get eventChangeCurrent() {
		return `cds-pagination-changed-current`;
	}
	/**
	* The name of the custom event fired after the number of rows per page is changed from `<cds-page-sizes-select>`.
	*/
	static get eventPageSizeChanged() {
		return `cds-page-sizes-select-changed`;
	}
	static {
		this.shadowRootOptions = {
			...LitElement.shadowRootOptions,
			delegatesFocus: true
		};
	}
	static {
		this.styles = pagination_default$1;
	}
};
__decorate([query(`cds-select`)], CDSPagination.prototype, "_pageSizeSelect", void 0);
__decorate([HostListener(`cds-select-selected`)], CDSPagination.prototype, "_handleChangeSelector", null);
__decorate([property({ attribute: "backward-text" })], CDSPagination.prototype, "backwardText", void 0);
__decorate([property({ attribute: "backward-text-tooltip-position" })], CDSPagination.prototype, "backwardTextTooltipPosition", void 0);
__decorate([property({
	type: Number,
	reflect: true
})], CDSPagination.prototype, "page", void 0);
__decorate([property({ attribute: false })], CDSPagination.prototype, "formatLabelText", void 0);
__decorate([property({ attribute: false })], CDSPagination.prototype, "formatStatusWithDeterminateTotal", void 0);
__decorate([property({ attribute: false })], CDSPagination.prototype, "formatStatusWithIndeterminateTotal", void 0);
__decorate([property({ attribute: false })], CDSPagination.prototype, "formatSupplementalText", void 0);
__decorate([property({
	type: Boolean,
	attribute: "is-last-page"
})], CDSPagination.prototype, "isLastPage", void 0);
__decorate([property({ attribute: "items-per-page-text" })], CDSPagination.prototype, "itemsPerPageText", void 0);
__decorate([property({
	type: Boolean,
	reflect: true
})], CDSPagination.prototype, "disabled", void 0);
__decorate([property({ attribute: "forward-text" })], CDSPagination.prototype, "forwardText", void 0);
__decorate([property({ attribute: "forward-text-tooltip-position" })], CDSPagination.prototype, "forwardTextTooltipPosition", void 0);
__decorate([property({
	type: Boolean,
	attribute: "page-input-disabled"
})], CDSPagination.prototype, "pageInputDisabled", void 0);
__decorate([property({
	type: Number,
	attribute: "page-size",
	reflect: true
})], CDSPagination.prototype, "pageSize", void 0);
__decorate([property({
	type: Boolean,
	attribute: "page-size-input-disabled"
})], CDSPagination.prototype, "pageSizeInputDisabled", void 0);
__decorate([property({ attribute: "page-size-label-text" })], CDSPagination.prototype, "pageSizeLabelText", void 0);
__decorate([property({
	type: Boolean,
	reflect: true,
	attribute: "pages-unknown"
})], CDSPagination.prototype, "pagesUnknown", void 0);
__decorate([property({ reflect: true })], CDSPagination.prototype, "size", void 0);
__decorate([property({ type: Number })], CDSPagination.prototype, "start", void 0);
__decorate([property({
	type: Number,
	attribute: "total-items",
	converter: { fromAttribute: (value) => value === null || value === "" ? void 0 : Number(value) }
})], CDSPagination.prototype, "totalItems", void 0);
__decorate([property({ type: Number })], CDSPagination.prototype, "totalPages", void 0);
CDSPagination = __decorate([carbonElement(`cds-pagination`)], CDSPagination);
var pagination_default = CDSPagination;
//#endregion
export { pagination_default as default };

//# sourceMappingURL=pagination.js.map