import React, { useState, forwardRef, Fragment, useRef, useEffect } from "react";
import { cx, isNumber } from "../../utils";
import { useForkRef } from "../../hooks";
import { PaginationPages, PaginationActions, PaginationButton, PaginationSection, PaginationButtonGroup, PaginationRoot, PaginationShorter, PaginationActionsLeft, PaginationHelperText } from "./Pagination.styles";
import { getSections, defaultValues } from "./utils";
import { base as viewCSS } from "./variations/_view/base";
import { base as typeCSS } from "./variations/_type/base";
import { base as sizeCSS } from "./variations/_size/base";
import { classes } from "./Pagination.tokens";
import { PaginationQuickJumpToPage } from "./ui/PaginationQuickJumpToPage/PaginationQuickJumpToPage";
import { PaginationSelectPerPage } from "./ui/PaginationSelectPerPage/PaginationSelectPerPage";
export const paginationRoot = (Root)=>/*#__PURE__*/ forwardRef(({ value: outerValue, defaultValue, helperText, singleLine, perPage: outerPerPage, defaultPerPage, slots = defaultValues.slots, view, viewCurrentPage, type = defaultValues.type, size, pilled = defaultValues.pilled, square = defaultValues.square, disabledPages = defaultValues.disabledPages, count = defaultValues.value, hasQuickJump = defaultValues.hasQuickJump, hasPerPage = defaultValues.hasPerPage, perPageList = defaultValues.perPageList, isCommonButtonStyles = defaultValues.isCommonButtonStyles, placeholderQuickJump = defaultValues.placeholderQuickJump, textQuickJump = defaultValues.textQuickJump, textPerPage = defaultValues.textPerPage, leftContent, rightContent, listWidth = 'fit-content', onChangePageValue, onChangePerPageValue, onChange, onFocusQuickJump, onBlurQuickJump, ...rest }, ref)=>{
        const [pageInner, setPageInner] = useState(defaultValue || defaultValues.value);
        const pageValue = outerValue ?? pageInner;
        const [perPageInner, setPerPageInner] = useState(hasPerPage ? defaultPerPage || defaultValues.perPage : undefined);
        const perPageValue = outerPerPage ?? perPageInner;
        const pagesRef = useRef(null);
        const [pagesWidth, setPagesWidth] = useState(0);
        const [rootWidth, setRootWidth] = useState(0);
        const rootRef = useRef(null);
        const forkRef = useForkRef(rootRef, ref);
        const pages = Math.ceil(count / (perPageValue || 1));
        const sections = getSections(pageValue, pages, slots);
        const typeClass = classes[`${type}Type`];
        const roundedClass = pilled ? 'circle-circle' : 'square-square';
        const withHasPerPageSelect = hasPerPage && !helperText ? classes.withHasPerPageSelect : undefined;
        const withHasQuickJump = hasQuickJump ? classes.withHasQuickJump : undefined;
        const disabled = disabledPages.map((el)=>isNumber(el) ? Number(el) : null);
        const pageSetter = (pageValueCandidate)=>{
            let newPageValue = pageValueCandidate ?? defaultValues.value;
            if (newPageValue === pageValue) {
                return;
            }
            if (newPageValue > pages) {
                newPageValue = pages;
            }
            if (newPageValue < 1) {
                newPageValue = 1;
            }
            if (disabled.includes(newPageValue)) {
                return;
            }
            setPageInner(newPageValue);
            return newPageValue;
        };
        const handleSetPage = (pageValueCandidate)=>{
            const newValue = pageSetter(pageValueCandidate);
            onChange?.(newValue, perPageValue);
            onChangePageValue?.(newValue);
        };
        const handlerSetPerPage = (newPerPageValue)=>{
            setPerPageInner(newPerPageValue);
            onChange?.(pageValue, newPerPageValue);
            onChangePerPageValue?.(newPerPageValue);
        };
        const handleClick = (currentPage)=>{
            if (isActiveButton(currentPage)) {
                return;
            }
            handleSetPage(currentPage);
        };
        const isActiveButton = (checkPage)=>{
            return pageValue === checkPage ? classes.paginationPageButtonActive : '';
        };
        useEffect(()=>{
            const observers = [];
            if (pagesRef.current) {
                const pagesObserver = new ResizeObserver((entries)=>{
                    const newWidth = entries[0].contentRect.width;
                    setPagesWidth(newWidth);
                });
                pagesObserver.observe(pagesRef.current);
                observers.push(pagesObserver);
            }
            if (rootRef.current) {
                const rootObserver = new ResizeObserver((entries)=>{
                    const newWidth = entries[0].contentRect.width;
                    setRootWidth(newWidth);
                });
                rootObserver.observe(rootRef.current);
                observers.push(rootObserver);
            }
            return ()=>{
                observers.forEach((observer)=>observer.disconnect());
            };
        }, [
            type
        ]);
        return /*#__PURE__*/ React.createElement(Root, {
            size: size,
            view: view,
            viewCurrentPage: viewCurrentPage,
            className: cx(classes.wrapper, typeClass),
            ref: forkRef,
            ...rest
        }, /*#__PURE__*/ React.createElement(PaginationRoot, {
            className: typeClass
        }, /*#__PURE__*/ React.createElement(PaginationPages, {
            ref: pagesRef
        }, leftContent && /*#__PURE__*/ React.createElement(PaginationButtonGroup, {
            isCommonButtonStyles: isCommonButtonStyles
        }, leftContent), sections && sections.map((section, indexSection)=>/*#__PURE__*/ React.createElement(Fragment, {
                key: indexSection
            }, indexSection !== 0 && /*#__PURE__*/ React.createElement(PaginationShorter, {
                stretching: "fixed",
                disabled: true,
                className: classes.buttonDisabled
            }, "..."), /*#__PURE__*/ React.createElement(PaginationSection, null, section.map((currentPage, index)=>/*#__PURE__*/ React.createElement(PaginationButton, {
                    key: `${currentPage}_${index}`,
                    className: cx(classes.paginationPageButton, isActiveButton(currentPage), disabled.includes(currentPage) ? classes.buttonDisabled : ''),
                    pin: roundedClass,
                    disabled: disabled.includes(currentPage),
                    square: square,
                    onClick: ()=>handleClick(currentPage)
                }, currentPage))))), rightContent && /*#__PURE__*/ React.createElement(PaginationButtonGroup, {
            isCommonButtonStyles: isCommonButtonStyles
        }, rightContent)), /*#__PURE__*/ React.createElement(PaginationActions, {
            style: type === 'compact' ? {
                minWidth: '0px'
            } : {
                width: `calc(100% - ${pagesWidth}px)`
            },
            className: cx(classes.actions, typeClass, withHasPerPageSelect, withHasQuickJump)
        }, /*#__PURE__*/ React.createElement(PaginationActionsLeft, {
            className: typeClass
        }, hasQuickJump && /*#__PURE__*/ React.createElement(PaginationQuickJumpToPage, {
            prevPageValue: pageValue,
            placeholderQuickJump: placeholderQuickJump,
            textQuickJump: textQuickJump,
            onChangeValue: handleSetPage,
            onFocusQuickJump: onFocusQuickJump,
            onBlurQuickJump: onBlurQuickJump
        }), helperText && /*#__PURE__*/ React.createElement(PaginationHelperText, {
            className: cx(typeClass, singleLine ? classes.ellipsisText : ''),
            style: {
                maxWidth: rootWidth
            }
        }, helperText)), hasPerPage && /*#__PURE__*/ React.createElement(PaginationSelectPerPage, {
            textPerPage: textPerPage,
            perPageValue: perPageValue,
            perPageList: perPageList,
            onChangeValue: handlerSetPerPage,
            size: size,
            listWidth: listWidth
        }))));
    });
export const paginationConfig = {
    name: 'Pagination',
    tag: 'div',
    layout: paginationRoot,
    base: '',
    variations: {
        view: {
            css: viewCSS
        },
        size: {
            css: sizeCSS
        },
        type: {
            css: typeCSS
        }
    },
    defaults: {
        view: 'clear',
        size: 'm'
    }
};
