/* *
 *
 *  Grid Pagination class
 *
 *  (c) 2020-2026 Highsoft AS
 *
 *  Integration of this software requires a license.
 *  - For commercial use, see www.highcharts.com/license
 *  - For non-commercial, see www.highcharts.com/license-eula
 *
 *
 *  Authors:
 *  - Sebastian Bochan
 *
 * */
'use strict';
import { createGridIcon } from '../UI/SvgIcons.js';
import Globals from '../Globals.js';
import GridUtils from '../GridUtils.js';
import AST from '../../../Core/Renderer/HTML/AST.js';
import { defined, fireEvent, isObject, merge } from '../../../Shared/Utilities.js';
const { makeHTMLElement, formatText, joinClassNames } = GridUtils;
const paginationAlignments = [
    'left',
    'center',
    'right',
    'distributed'
];
const alignmentClassName = (alignment) => `${Globals.classNamePrefix}pagination-${alignment}`;
/**
 *  Representing the pagination functionalities for the Grid.
 */
class Pagination {
    /* *
    *
    *  Constructor
    *
    * */
    /**
     * Construct the pagination object.
     *
     * @param grid
     * The Grid Table instance which the pagination controller belongs to.
     */
    constructor(grid) {
        this.grid = grid;
        this.controller = grid.querying.pagination;
    }
    /* *
    *
    *  Methods
    *
    * */
    /**
     * Returns the reference to the pagination options.
     */
    get options() {
        return this.grid.options?.pagination;
    }
    /**
     * Returns the language options for pagination text.
     */
    get lang() {
        return this.grid.options?.lang?.pagination;
    }
    /**
     * Returns the page size selector options.
     */
    get pageSizeSelectorOptions() {
        const raw = this.options?.controls?.pageSizeSelector;
        if (isObject(raw)) {
            return raw.options ?? [];
        }
        return (Pagination.defaultOptions
            .controls?.pageSizeSelector).options ?? [];
    }
    /**
     * Internal method to set the dirty flags for the pagination based on the
     * options differences.
     *
     * @param diff
     * The differences between the previous and the new options.
     *
     * @internal
     */
    update(diff) {
        if ('page' in diff ||
            'pageSize' in diff) {
            this.isDirtyQuerying = true;
            delete diff.page;
            delete diff.pageSize;
        }
        if ('alignment' in diff) {
            this.isDirtyAlignment = true;
            delete diff.alignment;
        }
        if ('className' in diff) {
            this.isDirtyClassName = true;
            delete diff.className;
        }
        // TODO: Optimize more options here.
        if (Object.keys(diff).length > 0) {
            this.grid.dirtyFlags.add('grid');
        }
    }
    /**
     * Render the pagination container.
     *
     * The pagination container is positioned based on the `position` option:
     * - `'top'`: Rendered before the table
     * - `'bottom'`: Rendered after the table (default)
     * - `'footer'`: Rendered inside a tfoot element
     * - `'#id'` or any string: Rendered inside a custom container with
     * the specified ID.
     */
    render() {
        const position = this.options?.position;
        const grid = this.grid;
        const alignmentClass = this.getAlignmentClass();
        this.oldTotalItems = this.controller.totalItems;
        // Set row count for a11y
        grid.tableElement?.setAttribute('aria-current', 'page');
        this.updateA11yRowsCount(this.controller.currentPageSize);
        // Render pagination container
        if (typeof position === 'string' && position.startsWith('#')) {
            this.renderCustomContainer(position);
        }
        else {
            if (position === 'footer') {
                this.renderFooter();
            }
            this.contentWrapper = makeHTMLElement('nav', {
                className: joinClassNames(Globals.getClassName('pagination'), alignmentClass, this.options?.className)
            }, position === 'footer' ?
                this.paginationContainer : grid.contentWrapper);
            this.contentWrapper.setAttribute('aria-label', 'Results pagination');
        }
        // Render all components
        this.renderPageInfo();
        this.renderControls();
        this.renderPageSizeSelector();
        // Update button states after rendering
        this.updateButtonStates();
    }
    getAlignmentClass() {
        const align = this.options?.align || '';
        return alignmentClassName(align);
    }
    updateAlignmentClass() {
        const wrapper = this.contentWrapper;
        if (!wrapper) {
            return;
        }
        const alignmentClasses = paginationAlignments.map(alignmentClassName);
        wrapper.classList.remove(...alignmentClasses);
        wrapper.classList.add(this.getAlignmentClass());
    }
    updateClassName() {
        const wrapper = this.contentWrapper;
        if (!wrapper) {
            return;
        }
        wrapper.className = joinClassNames(Globals.getClassName('pagination'), this.options?.className);
    }
    redraw() {
        if (this.isDirtyQuerying) {
            this.updateControls(true);
        }
        if (this.isDirtyClassName) {
            this.updateClassName();
        }
        if (this.isDirtyAlignment) {
            this.updateAlignmentClass();
        }
        delete this.isDirtyQuerying;
        delete this.isDirtyAlignment;
        delete this.isDirtyClassName;
    }
    /**
     * Render pagination in a tfoot element.
     */
    renderFooter() {
        const tableElement = this.grid.tableElement;
        if (!tableElement) {
            return;
        }
        // Create tfoot element
        const tfootElement = makeHTMLElement('tfoot', {}, tableElement);
        // Create tfoot row
        const tfootRow = makeHTMLElement('tr', {}, tfootElement);
        // Create tfoot cell with colspan and store it in paginationContainer
        this.paginationContainer = makeHTMLElement('td', {}, tfootRow);
        this.paginationContainer.setAttribute('colSpan', (this.grid.enabledColumns || []).length.toString());
        this.reflow();
    }
    /**
     * Render pagination in a custom container by ID.
     *
     * @param id
     * The ID of the custom container.
     */
    renderCustomContainer(id) {
        const customContainer = document.querySelector(id);
        if (!customContainer) {
            console.warn(`Pagination: Custom container with ID "${id}" not found.`); // eslint-disable-line no-console
            return;
        }
        this.paginationContainer = customContainer;
        const alignmentClass = this.getAlignmentClass();
        // Set content wrapper to the custom container
        this.contentWrapper = makeHTMLElement('div', {
            className: joinClassNames(Globals.getClassName('pagination'), alignmentClass, this.options?.className)
        }, customContainer);
    }
    /**
     * Render the page information text.
     */
    renderPageInfo() {
        const pageInfo = this.options?.controls?.pageInfo;
        if (pageInfo === false ||
            (isObject(pageInfo) && pageInfo.enabled === false)) {
            return;
        }
        this.pageInfoElement = makeHTMLElement('div', {
            className: joinClassNames(Globals.getClassName('paginationPageInfo'), pageInfo?.className)
        }, this.contentWrapper);
        this.updatePageInfo();
    }
    /**
     * Update the page information text.
     */
    updatePageInfo() {
        if (!this.pageInfoElement) {
            return;
        }
        const { currentPage, currentPageSize, totalItems, totalPages } = this.controller;
        const startItem = Math.min(Math.max(0, (currentPage - 1) * currentPageSize + 1), totalItems);
        const endItem = Math.min(currentPage * currentPageSize, totalItems);
        const pageInfoText = formatText(this.lang?.pageInfo ?? '', {
            start: startItem,
            end: endItem,
            total: totalItems,
            currentPage: currentPage,
            totalPages: totalPages
        });
        this.pageInfoElement.innerHTML = pageInfoText;
    }
    /**
     * Render the controls buttons and page numbers.
     */
    renderControls() {
        const navContainer = makeHTMLElement('div', {
            className: joinClassNames(Globals.getClassName('paginationControls'), this.options?.controls?.className)
        }, this.contentWrapper);
        const controls = this.options?.controls || {};
        // Render first/previous buttons
        if (controls.firstLastButtons) {
            this.renderFirstButton(navContainer);
        }
        // Render previous button
        if (controls.previousNextButtons) {
            this.renderPrevButton(navContainer);
        }
        // Render page numbers
        if (controls.pageButtons) {
            this.renderPageNumbers(navContainer);
        }
        // Render next button
        if (controls.previousNextButtons) {
            this.renderNextButton(navContainer);
        }
        // Render last/first buttons
        if (controls.firstLastButtons) {
            this.renderLastButton(navContainer);
        }
    }
    /**
     * Update the pagination controls.
     *
     * @param force
     * Whether to force update the controls.
     *
     * @internal
     */
    updateControls(force = false) {
        const { totalItems, currentPageSize } = this.controller;
        if (this.oldTotalItems === this.controller.totalItems && !force) {
            return;
        }
        this.updatePageInfo();
        this.updatePageNumbers();
        this.updateButtonStates();
        this.updateA11yRowsCount(currentPageSize);
        this.oldTotalItems = totalItems;
    }
    /**
     * Render the first page button.
     *
     * @param container
     * The container element for the first page button.
     *
     */
    renderFirstButton(container) {
        const firstLastButtons = this.options?.controls?.firstLastButtons;
        if (firstLastButtons === false ||
            (isObject(firstLastButtons) && firstLastButtons.enabled === false)) {
            return;
        }
        const firstIconEl = createGridIcon('doubleChevronLeft', this.grid.options?.rendering?.icons);
        this.firstButton = makeHTMLElement('button', {
            className: Globals.getClassName('button')
        }, container);
        this.firstButton.appendChild(firstIconEl);
        this.firstButton.title = this.lang?.firstPage ?? '';
        // Set aria-label for a11y
        this.firstButton.setAttribute('aria-label', this.lang?.firstPage ?? '');
        // Add click event
        this.firstButton.addEventListener('click', () => {
            void this.goToPage(1);
        });
        this.setButtonState(this.firstButton, this.controller.currentPage === 1);
    }
    /**
     * Render the previous page button.
     *
     * @param container
     * The container element for the previous page button.
     */
    renderPrevButton(container) {
        const previousNextButtons = this.options?.controls?.previousNextButtons;
        if (previousNextButtons === false ||
            (isObject(previousNextButtons) &&
                previousNextButtons.enabled === false)) {
            return;
        }
        const prevIconName = 'chevronLeft';
        const prevIconEl = createGridIcon(prevIconName, this.grid.options?.rendering?.icons);
        this.prevButton = makeHTMLElement('button', {
            className: Globals.getClassName('button')
        }, container);
        this.prevButton.appendChild(prevIconEl);
        this.prevButton.title = this.lang?.previousPage ?? '';
        // Set aria-label for a11y
        this.prevButton.setAttribute('aria-label', this.lang?.previousPage ?? '');
        // Add click event
        this.prevButton.addEventListener('click', () => {
            void this.goToPage(this.controller.currentPage - 1);
        });
        this.setButtonState(this.prevButton, this.controller.currentPage === 1);
    }
    /**
     * Render the next page button.
     *
     * @param container
     * The container element for the next page button.
     */
    renderNextButton(container) {
        const previousNextButtons = this.options?.controls?.previousNextButtons;
        if (previousNextButtons === false ||
            (isObject(previousNextButtons) &&
                previousNextButtons.enabled === false)) {
            return;
        }
        const nextIconName = 'chevronRight';
        const nextIconEl = createGridIcon(nextIconName, this.grid.options?.rendering?.icons);
        this.nextButton = makeHTMLElement('button', {
            className: Globals.getClassName('button')
        }, container);
        this.nextButton.appendChild(nextIconEl);
        this.nextButton.title = this.lang?.nextPage ?? '';
        // Set aria-label for a11y
        this.nextButton.setAttribute('aria-label', this.lang?.nextPage ?? '');
        // Add click event
        this.nextButton.addEventListener('click', () => {
            void this.goToPage(this.controller.currentPage + 1);
        });
        this.setButtonState(this.nextButton, this.controller.currentPage >= this.controller.totalPages);
    }
    /**
     * Render the last page button.
     *
     * @param container
     * The container element for the last page button.
     */
    renderLastButton(container) {
        const firstLastButtons = this.options?.controls?.firstLastButtons;
        if (firstLastButtons === false ||
            (isObject(firstLastButtons) && firstLastButtons.enabled === false)) {
            return;
        }
        const lastIconName = 'doubleChevronRight';
        const lastIconEl = createGridIcon(lastIconName, this.grid.options?.rendering?.icons);
        this.lastButton = makeHTMLElement('button', {
            className: Globals.getClassName('button')
        }, container);
        this.lastButton.appendChild(lastIconEl);
        this.lastButton.title = this.lang?.lastPage ?? '';
        // Set aria-label for a11y
        this.lastButton.setAttribute('aria-label', this.lang?.lastPage ?? '');
        // Add click event
        this.lastButton.addEventListener('click', () => {
            void this.goToPage(this.controller.totalPages);
        });
        this.setButtonState(this.lastButton, this.controller.currentPage >= this.controller.totalPages);
    }
    /**
     * Render page number buttons with ellipsis.
     *
     * @param container
     * The container element for the page number buttons.
     */
    renderPageNumbers(container) {
        const pageButtons = this.options?.controls?.pageButtons;
        if (pageButtons === false ||
            (isObject(pageButtons) && pageButtons.enabled === false)) {
            return;
        }
        this.pageNumbersContainer = makeHTMLElement('div', {
            className: Globals.getClassName('paginationPages')
        }, container);
        this.updatePageNumbers();
    }
    /**
     * Update page number buttons based on current page and total pages.
     */
    updatePageNumbers() {
        if (!this.pageNumbersContainer) {
            return;
        }
        // Clear existing page numbers
        this.pageNumbersContainer.innerHTML = AST.emptyHTML;
        const pageButtons = this.options?.controls?.pageButtons;
        const maxPageNumbers = isObject(pageButtons) ?
            pageButtons.count :
            (Pagination.defaultOptions.controls?.pageButtons).count; // eslint-disable-line
        if (!maxPageNumbers) {
            return;
        }
        const { totalPages, currentPage } = this.controller;
        if (totalPages <= maxPageNumbers) {
            // Show all page numbers if total pages is less than max
            for (let i = 1; i <= totalPages; i++) {
                this.createPageButton(i, i === currentPage);
            }
        }
        else {
            const elements = [];
            // Determine layout based on current page position
            const isNearStart = currentPage <= 3;
            const isNearEnd = currentPage >= totalPages - 2;
            if (isNearStart) {
                // -2 for ellipsis and last page
                const pagesToShow = maxPageNumbers - 2;
                const maxPages = Math.min(pagesToShow, totalPages - 1);
                for (let i = 1; i <= maxPages; i++) {
                    elements.push({ type: 'button', page: i });
                }
                if (totalPages > pagesToShow + 1) {
                    elements.push({ type: 'ellipsis' });
                    elements.push({ type: 'button', page: totalPages });
                }
            }
            else if (isNearEnd) {
                // -2 for first page and ellipsis
                const pagesToShow = maxPageNumbers - 2;
                let i = totalPages - pagesToShow + 1;
                elements.push({ type: 'button', page: 1 });
                elements.push({ type: 'ellipsis' });
                for (i; i <= totalPages; i++) {
                    elements.push({ type: 'button', page: i });
                }
            }
            else {
                // Always add first page
                elements.push({ type: 'button', page: 1 });
                // -4 for first, last, and two ellipsis
                const maxMiddlePages = maxPageNumbers - 4;
                const halfMiddle = Math.floor(maxMiddlePages / 2);
                let startPage = Math.max(2, currentPage - halfMiddle);
                let endPage = Math.min(totalPages - 1, currentPage + halfMiddle);
                // Adjust to ensure we have exactly maxMiddlePages
                if (endPage - startPage + 1 > maxMiddlePages) {
                    if (startPage === 2) {
                        endPage = startPage + maxMiddlePages - 1;
                    }
                    else {
                        startPage = endPage - maxMiddlePages + 1;
                    }
                }
                // Check if we actually need ellipsis
                const needFirstEllipsis = startPage > 2;
                const needLastEllipsis = endPage < totalPages - 1;
                if (!needFirstEllipsis && !needLastEllipsis) {
                    // -2 for first and last
                    const availableSlots = maxPageNumbers - 2;
                    startPage = 2;
                    endPage = Math.min(totalPages - 1, startPage + availableSlots - 1);
                }
                else if (!needFirstEllipsis) {
                    // -3 for first, last, and one ellipsis
                    const availableSlots = maxPageNumbers - 3;
                    startPage = 2;
                    endPage = Math.min(totalPages - 1, startPage + availableSlots - 1);
                }
                else if (!needLastEllipsis) {
                    // -3 for first, last, and one ellipsis
                    const availableSlots = maxPageNumbers - 3;
                    endPage = totalPages - 1;
                    startPage = Math.max(2, endPage - availableSlots + 1);
                }
                // Add first ellipsis
                if (needFirstEllipsis) {
                    elements.push({ type: 'ellipsis' });
                }
                // Add middle pages
                for (let i = startPage; i <= endPage; i++) {
                    elements.push({ type: 'button', page: i });
                }
                // Add last ellipsis
                if (needLastEllipsis) {
                    elements.push({ type: 'ellipsis' });
                }
                // Always add last page
                elements.push({ type: 'button', page: totalPages });
            }
            // Render all elements
            elements.forEach((element) => {
                if (element.type === 'button' && defined(element.page)) {
                    this.createPageButton(element.page, element.page === currentPage);
                }
                else if (element.type === 'ellipsis') {
                    this.createEllipsis();
                }
            });
        }
    }
    /**
     * Create a page number button.
     *
     * @param pageNumber
     * The page number to create a button for.
     *
     * @param isActive
     * Whether the page number button is active.
     */
    createPageButton(pageNumber, isActive) {
        if (!this.pageNumbersContainer) {
            return;
        }
        const button = makeHTMLElement('button', {
            className: Globals.getClassName('button'),
            innerHTML: pageNumber.toString()
        }, this.pageNumbersContainer);
        if (isActive) {
            button.classList.add(Globals.getClassName('buttonSelected'));
            button.setAttribute('aria-current', 'page');
        }
        button.title = formatText(this.lang?.pageNumber ?? '', { page: pageNumber });
        // Set aria-label for a11y
        button.setAttribute('aria-label', formatText(this.lang?.pageNumber ?? '', { page: pageNumber }));
        // Add click event
        button.addEventListener('click', () => {
            void this.goToPage(pageNumber);
        });
    }
    /**
     * Create an ellipsis element.
     */
    createEllipsis() {
        if (!this.pageNumbersContainer) {
            return;
        }
        const ellipsisElement = makeHTMLElement('span', {
            innerHTML: '...'
        }, this.pageNumbersContainer);
        ellipsisElement.title = this.lang?.ellipsis ?? '';
        // Set aria-label for a11y
        ellipsisElement.setAttribute('aria-hidden', true);
    }
    /**
     * Render the page size selector.
     */
    renderPageSizeSelector() {
        const pageSizeSelector = this.options?.controls?.pageSizeSelector;
        if (pageSizeSelector === false ||
            (isObject(pageSizeSelector) &&
                pageSizeSelector.enabled === false)) {
            return;
        }
        const container = makeHTMLElement('div', {
            className: joinClassNames(Globals.getClassName('paginationPageSize'), pageSizeSelector?.className)
        }, this.contentWrapper);
        makeHTMLElement('span', {
            innerHTML: this.lang?.pageSizeLabel ?? ''
        }, container);
        this.pageSizeSelect = makeHTMLElement('select', {
            className: Globals.getClassName('input'),
            id: Globals.getClassName('paginationPageSize')
        }, container);
        this.pageSizeSelectorOptions.forEach((option) => {
            const optionElement = document.createElement('option');
            optionElement.value = option.toString();
            optionElement.innerHTML = option.toString();
            if (option === this.controller.currentPageSize) {
                optionElement.selected = true;
            }
            this.pageSizeSelect?.appendChild(optionElement);
        });
        this.pageSizeSelect.addEventListener('change', () => {
            if (!this.pageSizeSelect) {
                return;
            }
            void this.setPageSize(parseInt(this.pageSizeSelect.value, 10));
        });
    }
    /**
     * Sets the new options for the pagination.
     *
     * @param newOptions
     * The new options to set.
     */
    setOptions(newOptions) {
        var _a, _b, _c;
        const userOptions = (_a = this.grid.userOptions).pagination ?? (_a.pagination = {});
        const options = ((_c = ((_b = this.grid).options ?? (_b.options = {}))).pagination ?? (_c.pagination = {}));
        merge(true, userOptions, newOptions);
        merge(true, options, newOptions);
    }
    /**
     * Set the page size and recalculate pagination.
     *
     * @param newPageSize
     * The new page size to set.
     */
    async setPageSize(newPageSize) {
        const oldPageSize = this.controller.currentPageSize;
        const langAccessibility = this.grid.options?.lang?.accessibility;
        fireEvent(this, 'beforePageSizeChange', {
            pageSize: oldPageSize,
            newPageSize: newPageSize
        });
        this.controller.setPageSize(newPageSize);
        this.controller.setPage(1);
        this.setOptions({
            pageSize: newPageSize,
            page: 1
        });
        // Update the grid's pagination range
        await this.updateGridPagination();
        // Update UI
        this.updatePageInfo();
        this.updatePageNumbers();
        this.updateButtonStates();
        // Update row count for a11y
        this.updateA11yRowsCount(this.controller.currentPageSize);
        // Announce the page size change
        this.grid.accessibility?.announce(langAccessibility?.pagination?.announcements?.pageSizeChange +
            ' ' + newPageSize);
        fireEvent(this, 'afterPageSizeChange', {
            pageSize: newPageSize,
            previousPageSize: oldPageSize
        });
    }
    /**
     * Navigate to a specific page.
     *
     * @param pageNumber
     * The page number to navigate to.
     */
    async goToPage(pageNumber) {
        const langAccessibility = this.grid.options?.lang?.accessibility;
        const { totalPages, currentPage, currentPageSize } = this.controller;
        if (pageNumber < 1 ||
            pageNumber > totalPages ||
            pageNumber === currentPage) {
            return;
        }
        const previousPage = currentPage;
        fireEvent(this, 'beforePageChange', {
            currentPage: currentPage,
            nextPage: pageNumber,
            pageSize: currentPageSize
        });
        this.controller.setPage(pageNumber);
        const newPage = this.controller.currentPage; // Take clamped page
        this.setOptions({
            page: newPage
        });
        await this.updateGridPagination();
        this.updatePageInfo();
        this.updatePageNumbers();
        this.updateButtonStates();
        // Announce the page change
        this.grid.accessibility?.announce(langAccessibility?.pagination?.announcements?.pageChange +
            ' ' + newPage);
        fireEvent(this, 'afterPageChange', {
            currentPage: newPage,
            previousPage: previousPage,
            pageSize: currentPageSize
        });
    }
    /**
     * Update the grid's pagination state.
     */
    async updateGridPagination() {
        // Update the viewport to reflect the new data
        await this.grid.viewport?.updateRows();
        // Scroll to top after page change
        const tBody = this.grid.viewport?.tbodyElement;
        if (tBody) {
            tBody.scrollTop = 0;
        }
    }
    /**
     * Update button states based on current page.
     */
    updateButtonStates() {
        const { currentPage, totalPages } = this.controller;
        if (this.firstButton) {
            this.setButtonState(this.firstButton, currentPage === 1);
        }
        if (this.prevButton) {
            this.setButtonState(this.prevButton, currentPage === 1);
        }
        if (this.nextButton) {
            this.setButtonState(this.nextButton, currentPage >= totalPages);
        }
        if (this.lastButton) {
            this.setButtonState(this.lastButton, currentPage >= totalPages);
        }
    }
    /**
     * Call modifier to replace items with new ones.
     *
     * @param isNextPage
     * Declare prev or next action triggered by button.
     * @returns
     */
    async updatePage(isNextPage = true) {
        const { currentPage } = this.controller;
        const newPage = isNextPage ? currentPage + 1 : currentPage - 1;
        await this.goToPage(newPage);
    }
    /**
     * Set button state (enabled/disabled).
     *
     * @param button
     * The button to set the state for.
     *
     * @param disabled
     * Whether the button should be disabled.
     */
    setButtonState(button, disabled) {
        if (disabled) {
            button.setAttribute('disabled', 'disabled');
        }
        else {
            button.removeAttribute('disabled');
        }
    }
    /**
     * Reflow the pagination container.
     */
    reflow() {
        const position = this.options?.position;
        if (!this.paginationContainer) {
            return;
        }
        if (position === 'footer') {
            // Set the width to match the table width
            this.paginationContainer.style.width =
                this.grid.tableElement?.offsetWidth + 'px';
            return;
        }
    }
    /**
     * Destroy the pagination instance.
     */
    destroy() {
        // Fixed container removal when switching from custom to footer.
        const tfoot = this.paginationContainer?.closest('tfoot');
        if (tfoot) {
            tfoot.remove();
        }
        else {
            this.contentWrapper?.remove();
        }
    }
    /**
     * Render the dropdown page selector (select dropdown).
     *
     * @param container
     * The container element for the dropdown page selector.
     */
    renderDropdownPageSelector(container) {
        if (this.controller.totalPages <= 1) {
            return;
        }
        const wrapper = makeHTMLElement('div', {
            className: Globals.getClassName('paginationNavDropdown')
        }, container);
        const select = makeHTMLElement('select', {
            className: Globals.getClassName('input'),
            id: Globals.getClassName('paginationNavDropdown')
        }, wrapper);
        this.dropdownPageSelector = select;
        this.updateDropdownPageSelector();
        // Add event listener for page change
        select.addEventListener('change', () => {
            const newPage = parseInt(select.value, 10);
            if (newPage !== this.controller.currentPage) {
                void this.goToPage(newPage);
            }
        });
    }
    /**
     * Updates the dropdown page selector DOM elements.
     */
    updateDropdownPageSelector() {
        const select = this.dropdownPageSelector;
        if (!select) {
            return;
        }
        const { totalPages, currentPage } = this.controller;
        select.innerHTML = AST.emptyHTML;
        // Add options for each page
        for (let i = 1; i <= totalPages; i++) {
            const option = makeHTMLElement('option', {}, select);
            option.value = i.toString();
            option.textContent = `Page ${i} of ${totalPages}`;
        }
        // Set current page as selected
        select.value = currentPage.toString();
    }
    /**
     * Update the row count for a11y.
     *
     * @param currentPageSize
     * The current page size.
     */
    updateA11yRowsCount(currentPageSize) {
        const grid = this.grid;
        grid.tableElement?.setAttribute('aria-rowcount', currentPageSize || this.controller.totalItems);
    }
}
/* *
*
*  Static Properties
*
* */
/**
 * Default options of the pagination.
 */
Pagination.defaultOptions = {
    enabled: false,
    page: 1,
    pageSize: 10,
    position: 'bottom',
    controls: {
        pageSizeSelector: {
            enabled: true,
            options: [10, 20, 50, 100]
        },
        pageInfo: {
            enabled: true
        },
        firstLastButtons: {
            enabled: true
        },
        previousNextButtons: {
            enabled: true
        },
        pageButtons: {
            enabled: true,
            count: 7
        }
    }
};
/* *
 *
 *  Default Export
 *
 * */
export default Pagination;
