"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "Dots", {
    enumerable: true,
    get: function() {
        return Dots;
    }
});
const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
const _classnames = /*#__PURE__*/ _interop_require_default(require("classnames"));
const _hooks = require("../../../../../hooks");
const _Carouseltokens = require("../../Carousel.tokens");
const _index = require("./utils/index");
const _Dotsstyles = require("./Dots.styles");
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
function _getRequireWildcardCache(nodeInterop) {
    if (typeof WeakMap !== "function") return null;
    var cacheBabelInterop = new WeakMap();
    var cacheNodeInterop = new WeakMap();
    return (_getRequireWildcardCache = function(nodeInterop) {
        return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
    })(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
    if (!nodeInterop && obj && obj.__esModule) {
        return obj;
    }
    if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
        return {
            default: obj
        };
    }
    var cache = _getRequireWildcardCache(nodeInterop);
    if (cache && cache.has(obj)) {
        return cache.get(obj);
    }
    var newObj = {
        __proto__: null
    };
    var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
    for(var key in obj){
        if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
            var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
            if (desc && (desc.get || desc.set)) {
                Object.defineProperty(newObj, key, desc);
            } else {
                newObj[key] = obj[key];
            }
        }
    }
    newObj.default = obj;
    if (cache) {
        cache.set(obj, newObj);
    }
    return newObj;
}
const SIZE = 16; // размер точки в px
const ANIMATION_DURATION = 0.3; // скорость анимации в секундах
const Dots = /*#__PURE__*/ (0, _react.memo)(({ index: originalIndex = 0, onChange, centered = false, count = 0, visibleCount: originalVisibleCount = 0 })=>{
    // Трансформируем входные параметры для корректной работы в дальнейшем
    const [index, visibleCount] = (0, _index.getInitialData)(originalIndex, count, originalVisibleCount);
    // Рефки на DOM-ноды
    const transitionWrapperRef = (0, _react.useRef)(null);
    const dotWrapperRef = (0, _react.useRef)(null);
    const leftAnimationWrapperRef = (0, _react.useRef)(null);
    const rightAnimationWrapperRef = (0, _react.useRef)(null);
    // Консистентные переменные
    const isAnimating = (0, _react.useRef)(false);
    const prevIndex = (0, _react.useRef)(-Infinity);
    const prevActiveIndex = (0, _react.useRef)(Infinity);
    const isRightDirection = index > prevIndex.current;
    const diffDotsRange = Math.abs(index - prevIndex.current);
    const activeIndex = (0, _index.getActiveIndex)(index, isRightDirection, count, visibleCount);
    const hiddenDotsLeft = activeIndex < index;
    const hiddenDotsRight = index + (visibleCount - 1 - activeIndex) < count - 1;
    const syncDotsState = ()=>{
        if (!dotWrapperRef.current || !transitionWrapperRef.current || !leftAnimationWrapperRef.current || !rightAnimationWrapperRef.current) {
            return;
        }
        dotWrapperRef.current.classList.remove(_Carouseltokens.classes.animating);
        transitionWrapperRef.current.classList.remove(_Carouseltokens.classes.animating);
        Array.from(dotWrapperRef.current.children).forEach((child)=>{
            child.classList.remove(...[
                _Carouseltokens.classes.active,
                _Carouseltokens.classes.animateOut,
                _Carouseltokens.classes.temporaryNatural,
                _Carouseltokens.classes.shrinking
            ]);
            const node = child;
            node.style.animationDelay = '';
            node.style.animationDuration = '';
        });
        dotWrapperRef.current.children[activeIndex]?.classList.add(_Carouseltokens.classes.active);
        if (centered) {
            transitionWrapperRef.current.style.transform = `translateX(${visibleCount * SIZE / 2 - SIZE / 2 - activeIndex * SIZE}px)`;
        } else {
            transitionWrapperRef.current.style.transform = 'translateX(0)';
        }
        leftAnimationWrapperRef.current.innerText = '';
        rightAnimationWrapperRef.current.innerText = '';
        prevIndex.current = index;
        prevActiveIndex.current = activeIndex;
        isAnimating.current = false;
    };
    const handleClick = (i)=>{
        if (isAnimating.current) return;
        if (onChange) {
            onChange(index + (i - activeIndex));
        }
    };
    const handleTransitionEnd = (event)=>{
        if (!dotWrapperRef || !dotWrapperRef.current || !transitionWrapperRef || !transitionWrapperRef.current || !rightAnimationWrapperRef || !rightAnimationWrapperRef.current || !leftAnimationWrapperRef || !leftAnimationWrapperRef.current) {
            return;
        }
        if (event.target !== event.currentTarget || event.propertyName !== 'transform') {
            return;
        }
        syncDotsState();
    };
    (0, _react.useLayoutEffect)(()=>{
        if (!dotWrapperRef || !dotWrapperRef.current || !transitionWrapperRef || !transitionWrapperRef.current) {
            return;
        }
        // Вычисляем начальный сдвиг по горизонтали, чтобы точка стала по центру
        if (centered) {
            transitionWrapperRef.current.style.transform = `translateX(${visibleCount * SIZE / 2 - SIZE / 2 - activeIndex * SIZE}px)`;
        }
        prevIndex.current = index;
        prevActiveIndex.current = activeIndex;
    }, []);
    (0, _hooks.useDidMountLayoutEffect)(()=>{
        if (!dotWrapperRef || !dotWrapperRef.current || !transitionWrapperRef || !transitionWrapperRef.current || !leftAnimationWrapperRef || !leftAnimationWrapperRef.current || !rightAnimationWrapperRef || !rightAnimationWrapperRef.current) {
            return;
        }
        if (isAnimating.current) {
            syncDotsState();
            return;
        }
        isAnimating.current = true;
        dotWrapperRef.current.classList.add(_Carouseltokens.classes.animating);
        transitionWrapperRef.current.classList.add(_Carouseltokens.classes.animating);
        const targetIndex = (0, _index.getTargetIndex)(index, prevIndex.current, prevActiveIndex.current, diffDotsRange, visibleCount);
        const dotsToAdd = Math.abs(targetIndex - activeIndex);
        if (dotsToAdd === 0) {
            syncDotsState();
            return;
        }
        if (centered) {
            transitionWrapperRef.current.style.transform = `translateX(${visibleCount * SIZE / 2 - SIZE / 2 - targetIndex * SIZE}px)`;
        } else if (dotsToAdd > 0) {
            transitionWrapperRef.current.style.transform = `translateX(${-SIZE * (targetIndex - activeIndex)}px)`;
        }
        // Стираем все активные классы и устанавливаем активный класс на таргет.
        // В конце анимации произойдет переопределение активного класса.
        Array.from(dotWrapperRef.current.children).forEach((child)=>{
            child.classList.remove(_Carouseltokens.classes.active);
        });
        dotWrapperRef.current.children[targetIndex]?.classList.add(_Carouseltokens.classes.active);
        if (index > prevIndex.current) {
            // Двигаемся вправо
            // Если мы добавляем 1 и более точек, то нужно начать
            // приводить размер крайней правой точки (что будет в m размере?)
            // к натуральному размеру
            if (dotsToAdd >= 1) {
                dotWrapperRef.current.children[visibleCount - 1]?.classList.add(_Carouseltokens.classes.temporaryNatural);
            }
            // Т.к. мы двигаемся вправо, то нужно начать уменьшать размер крайней левой точки
            // (опять же, что в m size?)
            if (dotsToAdd >= 1) {
                dotWrapperRef.current.children[dotsToAdd]?.classList.add(_Carouseltokens.classes.shrinking);
            }
            if (dotsToAdd > 0) {
                for(let i = 0; i < dotsToAdd; i++){
                    const node = document.createElement('div');
                    node.textContent = '';
                    node.classList.add(_Carouseltokens.classes.dot);
                    node.style.opacity = '0';
                    const delay = i * (ANIMATION_DURATION / dotsToAdd);
                    node.style.animationDelay = `${delay}s`;
                    rightAnimationWrapperRef.current.appendChild(node);
                    const duration = ANIMATION_DURATION / dotsToAdd;
                    requestAnimationFrame(()=>{
                        node.classList.add(_Carouseltokens.classes.animateIn);
                        node.style.animationDuration = `${duration}s`;
                    });
                    const currentDomNode = dotWrapperRef.current.children?.[i];
                    if (!currentDomNode) {
                        return;
                    }
                    currentDomNode.classList.add(_Carouseltokens.classes.animateOut);
                    currentDomNode.style.animationDelay = `${delay}s`;
                    currentDomNode.style.animationDuration = `${duration}s`;
                }
            }
        } else {
            // Двигаемся влево
            // Если мы добавляем 1 и более точек, то нужно начать
            // приводить размер крайней левой точки (что будет в m размере?)
            // к натуральному размеру.
            if (dotsToAdd >= 1) {
                dotWrapperRef.current.children[0]?.classList.add(_Carouseltokens.classes.temporaryNatural);
            }
            // Т.к. мы двигаемся влево, то нужно начать уменьшать размер крайней правой точки
            // (опять же, что в m size?)
            if (dotsToAdd >= 1) {
                dotWrapperRef.current.children[visibleCount - 1 - dotsToAdd]?.classList.add(_Carouseltokens.classes.shrinking);
            }
            if (dotsToAdd > 0) {
                for(let i = dotsToAdd - 1; i >= 0; i--){
                    const node = document.createElement('div');
                    node.textContent = '';
                    node.classList.add(_Carouseltokens.classes.dot);
                    node.style.opacity = '0';
                    const delay = (dotsToAdd - 1 - i) * (ANIMATION_DURATION / dotsToAdd);
                    node.style.animationDelay = `${delay}s`;
                    leftAnimationWrapperRef.current.prepend(node);
                    const duration = ANIMATION_DURATION / dotsToAdd;
                    requestAnimationFrame(()=>{
                        node.classList.add(_Carouseltokens.classes.animateIn);
                        node.style.animationDuration = `${duration}s`;
                    });
                    const currentDomNode = dotWrapperRef.current.children?.[dotWrapperRef.current.children.length - 1 - i];
                    if (!currentDomNode) {
                        return;
                    }
                    currentDomNode.classList.add(_Carouseltokens.classes.animateOut);
                    currentDomNode.style.animationDelay = `${i * (ANIMATION_DURATION / dotsToAdd)}s`;
                    currentDomNode.style.animationDuration = `${duration}s`;
                }
            }
        }
    }, [
        index
    ]);
    return /*#__PURE__*/ _react.default.createElement(_Dotsstyles.Wrapper, null, /*#__PURE__*/ _react.default.createElement(_Dotsstyles.TransitionWrapper, {
        ref: transitionWrapperRef,
        onTransitionEnd: handleTransitionEnd
    }, /*#__PURE__*/ _react.default.createElement(_Dotsstyles.LeftAnimationWrapper, {
        ref: leftAnimationWrapperRef
    }), /*#__PURE__*/ _react.default.createElement(_Dotsstyles.DotWrapper, {
        ref: dotWrapperRef,
        className: (0, _classnames.default)(hiddenDotsLeft && _Carouseltokens.classes.availableDotsLeft, hiddenDotsRight && _Carouseltokens.classes.availableDotsRight)
    }, Array(visibleCount).fill(0).map((_, i)=>{
        return /*#__PURE__*/ _react.default.createElement("div", {
            key: i,
            className: (0, _classnames.default)(_Carouseltokens.classes.dot, i === activeIndex && _Carouseltokens.classes.active),
            onClick: ()=>handleClick(i)
        });
    })), /*#__PURE__*/ _react.default.createElement(_Dotsstyles.RightAnimationWrapper, {
        ref: rightAnimationWrapperRef
    })));
});
