// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useRef, useState } from 'react';
import clsx from 'clsx';
import { copyAnalyticsMetadataAttribute, getAnalyticsMetadataAttribute, } from '@cloudscape-design/component-toolkit/internal/analytics-metadata';
import InternalButton from '../button/internal';
import { useInternalI18n } from '../i18n/context';
import InternalIcon from '../icon/internal';
import InternalInput from '../input/internal';
import { getBaseProps } from '../internal/base-component';
import { useTableComponentsContext } from '../internal/context/table-component-context';
import { fireNonCancelableEvent } from '../internal/events';
import { usePrevious } from '../internal/hooks/use-previous';
import InternalPopover from '../popover/internal';
import InternalSpaceBetween from '../space-between/internal';
import { getPaginationState, range } from './utils';
import styles from './styles.css.js';
function PageButton({ className, ariaLabel, disabled, pageIndex, isCurrent = false, children, onClick, ...rest }) {
    function handleClick(event) {
        event.preventDefault();
        onClick(pageIndex);
    }
    return (React.createElement("li", { className: styles['page-item'], ...copyAnalyticsMetadataAttribute(rest) },
        React.createElement("button", { className: clsx(className, styles.button, disabled && styles['button-disabled'], isCurrent && styles['button-current']), type: "button", "aria-label": ariaLabel, disabled: disabled, onClick: handleClick, "aria-current": isCurrent, ...(disabled
                ? {}
                : getAnalyticsMetadataAttribute({
                    action: 'click',
                    detail: {
                        label: { root: 'self' },
                    },
                })) }, children)));
}
function PageNumber({ pageIndex, ...rest }) {
    return (React.createElement(PageButton, { className: styles['page-number'], pageIndex: pageIndex, ...rest, ...(rest.disabled
            ? {}
            : getAnalyticsMetadataAttribute({
                detail: {
                    position: `${pageIndex}`,
                },
            })) }, pageIndex));
}
const InternalPagination = React.forwardRef(({ openEnd, currentPageIndex, ariaLabels, i18nStrings, pagesCount, disabled, onChange, onNextPageClick, onPreviousPageClick, __internalRootRef, jumpToPage, ...rest }, ref) => {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j;
    const baseProps = getBaseProps(rest);
    const { leftDots, leftIndex, rightIndex, rightDots } = getPaginationState(currentPageIndex, pagesCount, openEnd);
    const [jumpToPageValue, setJumpToPageValue] = useState(currentPageIndex === null || currentPageIndex === void 0 ? void 0 : currentPageIndex.toString());
    const previousLoading = usePrevious(jumpToPage === null || jumpToPage === void 0 ? void 0 : jumpToPage.loading);
    const jumpToPageInputRef = useRef(null);
    const [hasError, setHasError] = useState(false);
    const i18n = useInternalI18n('pagination');
    // Expose setError function via ref
    React.useImperativeHandle(ref, () => ({
        setError: (error) => setHasError(error),
    }));
    // Sync input with currentPageIndex after loading completes
    React.useEffect(() => {
        if (previousLoading && !(jumpToPage === null || jumpToPage === void 0 ? void 0 : jumpToPage.loading)) {
            setJumpToPageValue(String(currentPageIndex));
        }
    }, [previousLoading, jumpToPage === null || jumpToPage === void 0 ? void 0 : jumpToPage.loading, currentPageIndex]);
    const paginationLabel = (_a = ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.paginationLabel) !== null && _a !== void 0 ? _a : '';
    const nextPageLabel = (_b = i18n('ariaLabels.nextPageLabel', ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.nextPageLabel)) !== null && _b !== void 0 ? _b : '';
    const previousPageLabel = (_c = i18n('ariaLabels.previousPageLabel', ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.previousPageLabel)) !== null && _c !== void 0 ? _c : '';
    const pageNumberLabelFn = (_d = i18n('ariaLabels.pageLabel', ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.pageLabel, format => pageNumber => format({ pageNumber }))) !== null && _d !== void 0 ? _d : ((pageNumber) => `${pageNumber}`);
    const jumpToPageLabel = (_e = i18n('i18nStrings.jumpToPageInputLabel', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.jumpToPageInputLabel)) !== null && _e !== void 0 ? _e : '';
    const jumpToPageButtonLabel = (_f = i18n('ariaLabels.jumpToPageButtonLabel', ariaLabels === null || ariaLabels === void 0 ? void 0 : ariaLabels.jumpToPageButton)) !== null && _f !== void 0 ? _f : '';
    const jumpToPageError = (_g = i18n('i18nStrings.jumpToPageError', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.jumpToPageError)) !== null && _g !== void 0 ? _g : '';
    const jumpToPageLoadingText = (_h = i18n('i18nStrings.jumpToPageLoadingText', i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.jumpToPageLoadingText)) !== null && _h !== void 0 ? _h : '';
    function handlePrevPageClick(requestedPageIndex) {
        handlePageClick(requestedPageIndex);
        fireNonCancelableEvent(onPreviousPageClick, {
            requestedPageAvailable: true,
            requestedPageIndex: requestedPageIndex,
        });
    }
    function handleNextPageClick(requestedPageIndex) {
        handlePageClick(requestedPageIndex);
        fireNonCancelableEvent(onNextPageClick, {
            requestedPageAvailable: currentPageIndex < pagesCount,
            requestedPageIndex: requestedPageIndex,
        });
    }
    function handlePageClick(requestedPageIndex, errorState) {
        setJumpToPageValue(String(requestedPageIndex));
        setHasError(!!errorState); // Clear error on successful navigation
        fireNonCancelableEvent(onChange, { currentPageIndex: requestedPageIndex });
    }
    function handleJumpToPageClick(requestedPageIndex) {
        var _a;
        const adjustedIndex = Math.max(1, Math.floor(requestedPageIndex));
        if (openEnd) {
            // Open-end: always navigate, parent will handle async loading
            handlePageClick(adjustedIndex);
        }
        else {
            // Closed-end: validate range
            if (adjustedIndex >= 1 && adjustedIndex <= pagesCount) {
                handlePageClick(adjustedIndex);
            }
            else {
                // Out of range - set error and navigate to last page
                handlePageClick(pagesCount, true);
            }
        }
        (_a = jumpToPageInputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
    }
    // Auto-clear error when user types in the input
    const handleInputChange = (e) => {
        setJumpToPageValue(e.detail.value);
        if (hasError) {
            setHasError(false);
        }
    };
    const previousButtonDisabled = disabled || currentPageIndex === 1;
    const nextButtonDisabled = disabled || (!openEnd && (pagesCount === 0 || currentPageIndex === pagesCount));
    const tableComponentContext = useTableComponentsContext();
    if ((_j = tableComponentContext === null || tableComponentContext === void 0 ? void 0 : tableComponentContext.paginationRef) === null || _j === void 0 ? void 0 : _j.current) {
        tableComponentContext.paginationRef.current.currentPageIndex = currentPageIndex;
        tableComponentContext.paginationRef.current.totalPageCount = pagesCount;
        tableComponentContext.paginationRef.current.openEnd = openEnd;
    }
    const jumpToPageButton = (React.createElement(InternalButton, { iconName: "arrow-right", variant: "icon", loading: jumpToPage === null || jumpToPage === void 0 ? void 0 : jumpToPage.loading, loadingText: jumpToPageLoadingText, ariaLabel: (jumpToPage === null || jumpToPage === void 0 ? void 0 : jumpToPage.loading) ? jumpToPageLoadingText : jumpToPageButtonLabel, onClick: () => handleJumpToPageClick(Number(jumpToPageValue)), disabled: !jumpToPageValue || Number(jumpToPageValue) === currentPageIndex }));
    return (React.createElement("ul", { "aria-label": paginationLabel, ...baseProps, className: clsx(baseProps.className, styles.root, disabled && styles['root-disabled']), ref: __internalRootRef },
        React.createElement(PageButton, { className: styles.arrow, pageIndex: currentPageIndex - 1, ariaLabel: previousPageLabel, disabled: previousButtonDisabled, onClick: handlePrevPageClick, ...(previousButtonDisabled
                ? {}
                : getAnalyticsMetadataAttribute({
                    detail: {
                        position: 'prev',
                    },
                })) },
            React.createElement(InternalIcon, { name: "angle-left", variant: disabled ? 'disabled' : 'normal' })),
        React.createElement(PageNumber, { pageIndex: 1, isCurrent: currentPageIndex === 1, disabled: disabled, ariaLabel: pageNumberLabelFn(1), onClick: handlePageClick }),
        leftDots && React.createElement("li", { className: styles.dots }, "..."),
        range(leftIndex, rightIndex).map(pageIndex => (React.createElement(PageNumber, { key: pageIndex, isCurrent: currentPageIndex === pageIndex, pageIndex: pageIndex, disabled: disabled, ariaLabel: pageNumberLabelFn(pageIndex), onClick: handlePageClick }))),
        rightDots && React.createElement("li", { className: styles.dots }, "..."),
        !openEnd && pagesCount > 1 && (React.createElement(PageNumber, { isCurrent: currentPageIndex === pagesCount, pageIndex: pagesCount, disabled: disabled, ariaLabel: pageNumberLabelFn(pagesCount), onClick: handlePageClick })),
        React.createElement(PageButton, { className: styles.arrow, pageIndex: currentPageIndex + 1, ariaLabel: nextPageLabel, disabled: nextButtonDisabled, onClick: handleNextPageClick, ...(nextButtonDisabled
                ? {}
                : getAnalyticsMetadataAttribute({
                    detail: {
                        position: 'next',
                    },
                })) },
            React.createElement(InternalIcon, { name: "angle-right", variant: disabled ? 'disabled' : 'normal' })),
        jumpToPage && (React.createElement("li", { className: styles['jump-to-page'] },
            React.createElement(InternalSpaceBetween, { size: "xxs", direction: "horizontal", alignItems: "end" },
                React.createElement("div", { className: styles['jump-to-page-input'] },
                    React.createElement(InternalInput, { ref: jumpToPageInputRef, type: "number", value: jumpToPageValue, __inlineLabelText: jumpToPageLabel || undefined, __fullWidth: true, ariaLabel: jumpToPageLabel || undefined, nativeInputAttributes: {
                            min: 1,
                            max: !openEnd ? pagesCount : undefined,
                        }, onChange: handleInputChange, onBlur: () => setHasError(false), onKeyDown: e => {
                            if (e.detail.keyCode === 13 && jumpToPageValue && Number(jumpToPageValue) !== currentPageIndex) {
                                handleJumpToPageClick(Number(jumpToPageValue));
                            }
                        } })),
                hasError && !(jumpToPage === null || jumpToPage === void 0 ? void 0 : jumpToPage.loading) ? (React.createElement(InternalPopover, { size: "medium", dismissButton: false, __visible: true, content: jumpToPageError, position: "bottom", triggerType: "custom", __onVisibleChange: ({ detail }) => !detail.visible && setHasError(false) }, jumpToPageButton)) : (jumpToPageButton))))));
});
export default InternalPagination;
//# sourceMappingURL=internal.js.map