function _array_like_to_array(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
    return arr2;
}
function _array_with_holes(arr) {
    if (Array.isArray(arr)) return arr;
}
function _iterable_to_array_limit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;
    var _s, _e;
    try {
        for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
            _arr.push(_s.value);
            if (i && _arr.length === i) break;
        }
    } catch (err) {
        _d = true;
        _e = err;
    } finally{
        try {
            if (!_n && _i["return"] != null) _i["return"]();
        } finally{
            if (_d) throw _e;
        }
    }
    return _arr;
}
function _non_iterable_rest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _sliced_to_array(arr, i) {
    return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _type_of(obj) {
    "@swc/helpers - typeof";
    return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
function _unsupported_iterable_to_array(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _array_like_to_array(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(n);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
import React, { memo, useRef, useLayoutEffect } from "react";
import cls from "classnames";
import { useDidMountLayoutEffect } from "../../../../../hooks";
import { classes } from "../../Carousel.tokens";
import { getActiveIndex, getTargetIndex, getInitialData } from "./utils/index";
import { Wrapper, DotWrapper, RightAnimationWrapper, LeftAnimationWrapper, TransitionWrapper } from "./Dots.styles";
var SIZE = 16; // размер точки в px
var ANIMATION_DURATION = 0.3; // скорость анимации в секундах
export var Dots = /*#__PURE__*/ memo(function(param) {
    var tmp = param.index, originalIndex = tmp === void 0 ? 0 : tmp, onChange = param.onChange, _param_centered = param.centered, centered = _param_centered === void 0 ? false : _param_centered, _param_count = param.count, count = _param_count === void 0 ? 0 : _param_count, tmp1 = param.visibleCount, originalVisibleCount = tmp1 === void 0 ? 0 : tmp1;
    // Трансформируем входные параметры для корректной работы в дальнейшем
    var _getInitialData = _sliced_to_array(getInitialData(originalIndex, count, originalVisibleCount), 2), index = _getInitialData[0], visibleCount = _getInitialData[1];
    // Рефки на DOM-ноды
    var transitionWrapperRef = useRef(null);
    var dotWrapperRef = useRef(null);
    var leftAnimationWrapperRef = useRef(null);
    var rightAnimationWrapperRef = useRef(null);
    // Консистентные переменные
    var isAnimating = useRef(false);
    var prevIndex = useRef(-Infinity);
    var prevActiveIndex = useRef(Infinity);
    var isRightDirection = index > prevIndex.current;
    var diffDotsRange = Math.abs(index - prevIndex.current);
    var activeIndex = getActiveIndex(index, isRightDirection, count, visibleCount);
    var hiddenDotsLeft = activeIndex < index;
    var hiddenDotsRight = index + (visibleCount - 1 - activeIndex) < count - 1;
    var syncDotsState = function syncDotsState() {
        var _dotWrapperRef_current_children_activeIndex;
        if (!dotWrapperRef.current || !transitionWrapperRef.current || !leftAnimationWrapperRef.current || !rightAnimationWrapperRef.current) {
            return;
        }
        dotWrapperRef.current.classList.remove(classes.animating);
        transitionWrapperRef.current.classList.remove(classes.animating);
        Array.from(dotWrapperRef.current.children).forEach(function(child) {
            var _child_classList;
            (_child_classList = child.classList).remove.apply(_child_classList, [
                classes.active,
                classes.animateOut,
                classes.temporaryNatural,
                classes.shrinking
            ]);
            var node = child;
            node.style.animationDelay = '';
            node.style.animationDuration = '';
        });
        (_dotWrapperRef_current_children_activeIndex = dotWrapperRef.current.children[activeIndex]) === null || _dotWrapperRef_current_children_activeIndex === void 0 ? void 0 : _dotWrapperRef_current_children_activeIndex.classList.add(classes.active);
        if (centered) {
            transitionWrapperRef.current.style.transform = "translateX(".concat(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;
    };
    var handleClick = function handleClick(i) {
        if (isAnimating.current) return;
        if (onChange) {
            onChange(index + (i - activeIndex));
        }
    };
    var handleTransitionEnd = function 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();
    };
    useLayoutEffect(function() {
        if (!dotWrapperRef || !dotWrapperRef.current || !transitionWrapperRef || !transitionWrapperRef.current) {
            return;
        }
        // Вычисляем начальный сдвиг по горизонтали, чтобы точка стала по центру
        if (centered) {
            transitionWrapperRef.current.style.transform = "translateX(".concat(visibleCount * SIZE / 2 - SIZE / 2 - activeIndex * SIZE, "px)");
        }
        prevIndex.current = index;
        prevActiveIndex.current = activeIndex;
    }, []);
    useDidMountLayoutEffect(function() {
        var _dotWrapperRef_current_children_targetIndex;
        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(classes.animating);
        transitionWrapperRef.current.classList.add(classes.animating);
        var targetIndex = getTargetIndex(index, prevIndex.current, prevActiveIndex.current, diffDotsRange, visibleCount);
        var dotsToAdd = Math.abs(targetIndex - activeIndex);
        if (dotsToAdd === 0) {
            syncDotsState();
            return;
        }
        if (centered) {
            transitionWrapperRef.current.style.transform = "translateX(".concat(visibleCount * SIZE / 2 - SIZE / 2 - targetIndex * SIZE, "px)");
        } else if (dotsToAdd > 0) {
            transitionWrapperRef.current.style.transform = "translateX(".concat(-SIZE * (targetIndex - activeIndex), "px)");
        }
        // Стираем все активные классы и устанавливаем активный класс на таргет.
        // В конце анимации произойдет переопределение активного класса.
        Array.from(dotWrapperRef.current.children).forEach(function(child) {
            child.classList.remove(classes.active);
        });
        (_dotWrapperRef_current_children_targetIndex = dotWrapperRef.current.children[targetIndex]) === null || _dotWrapperRef_current_children_targetIndex === void 0 ? void 0 : _dotWrapperRef_current_children_targetIndex.classList.add(classes.active);
        if (index > prevIndex.current) {
            // Двигаемся вправо
            // Если мы добавляем 1 и более точек, то нужно начать
            // приводить размер крайней правой точки (что будет в m размере?)
            // к натуральному размеру
            if (dotsToAdd >= 1) {
                var _dotWrapperRef_current_children_;
                (_dotWrapperRef_current_children_ = dotWrapperRef.current.children[visibleCount - 1]) === null || _dotWrapperRef_current_children_ === void 0 ? void 0 : _dotWrapperRef_current_children_.classList.add(classes.temporaryNatural);
            }
            // Т.к. мы двигаемся вправо, то нужно начать уменьшать размер крайней левой точки
            // (опять же, что в m size?)
            if (dotsToAdd >= 1) {
                var _dotWrapperRef_current_children_dotsToAdd;
                (_dotWrapperRef_current_children_dotsToAdd = dotWrapperRef.current.children[dotsToAdd]) === null || _dotWrapperRef_current_children_dotsToAdd === void 0 ? void 0 : _dotWrapperRef_current_children_dotsToAdd.classList.add(classes.shrinking);
            }
            if (dotsToAdd > 0) {
                var _loop = function(i) {
                    var _dotWrapperRef_current_children;
                    var node = document.createElement('div');
                    node.textContent = '';
                    node.classList.add(classes.dot);
                    node.style.opacity = '0';
                    var delay = i * (ANIMATION_DURATION / dotsToAdd);
                    node.style.animationDelay = "".concat(delay, "s");
                    rightAnimationWrapperRef.current.appendChild(node);
                    var duration = ANIMATION_DURATION / dotsToAdd;
                    requestAnimationFrame(function() {
                        node.classList.add(classes.animateIn);
                        node.style.animationDuration = "".concat(duration, "s");
                    });
                    var currentDomNode = (_dotWrapperRef_current_children = dotWrapperRef.current.children) === null || _dotWrapperRef_current_children === void 0 ? void 0 : _dotWrapperRef_current_children[i];
                    if (!currentDomNode) {
                        return {
                            v: void void 0
                        };
                    }
                    currentDomNode.classList.add(classes.animateOut);
                    currentDomNode.style.animationDelay = "".concat(delay, "s");
                    currentDomNode.style.animationDuration = "".concat(duration, "s");
                };
                for(var i = 0; i < dotsToAdd; i++){
                    var _ret = _loop(i);
                    if (_type_of(_ret) === "object") return _ret.v;
                }
            }
        } else {
            // Двигаемся влево
            // Если мы добавляем 1 и более точек, то нужно начать
            // приводить размер крайней левой точки (что будет в m размере?)
            // к натуральному размеру.
            if (dotsToAdd >= 1) {
                var _dotWrapperRef_current_children_1;
                (_dotWrapperRef_current_children_1 = dotWrapperRef.current.children[0]) === null || _dotWrapperRef_current_children_1 === void 0 ? void 0 : _dotWrapperRef_current_children_1.classList.add(classes.temporaryNatural);
            }
            // Т.к. мы двигаемся влево, то нужно начать уменьшать размер крайней правой точки
            // (опять же, что в m size?)
            if (dotsToAdd >= 1) {
                var _dotWrapperRef_current_children_2;
                (_dotWrapperRef_current_children_2 = dotWrapperRef.current.children[visibleCount - 1 - dotsToAdd]) === null || _dotWrapperRef_current_children_2 === void 0 ? void 0 : _dotWrapperRef_current_children_2.classList.add(classes.shrinking);
            }
            if (dotsToAdd > 0) {
                var _loop1 = function(i1) {
                    var _dotWrapperRef_current_children;
                    var node = document.createElement('div');
                    node.textContent = '';
                    node.classList.add(classes.dot);
                    node.style.opacity = '0';
                    var delay = (dotsToAdd - 1 - i1) * (ANIMATION_DURATION / dotsToAdd);
                    node.style.animationDelay = "".concat(delay, "s");
                    leftAnimationWrapperRef.current.prepend(node);
                    var duration = ANIMATION_DURATION / dotsToAdd;
                    requestAnimationFrame(function() {
                        node.classList.add(classes.animateIn);
                        node.style.animationDuration = "".concat(duration, "s");
                    });
                    var currentDomNode = (_dotWrapperRef_current_children = dotWrapperRef.current.children) === null || _dotWrapperRef_current_children === void 0 ? void 0 : _dotWrapperRef_current_children[dotWrapperRef.current.children.length - 1 - i1];
                    if (!currentDomNode) {
                        return {
                            v: void void 0
                        };
                    }
                    currentDomNode.classList.add(classes.animateOut);
                    currentDomNode.style.animationDelay = "".concat(i1 * (ANIMATION_DURATION / dotsToAdd), "s");
                    currentDomNode.style.animationDuration = "".concat(duration, "s");
                };
                for(var i1 = dotsToAdd - 1; i1 >= 0; i1--){
                    var _ret1 = _loop1(i1);
                    if (_type_of(_ret1) === "object") return _ret1.v;
                }
            }
        }
    }, [
        index
    ]);
    return /*#__PURE__*/ React.createElement(Wrapper, null, /*#__PURE__*/ React.createElement(TransitionWrapper, {
        ref: transitionWrapperRef,
        onTransitionEnd: handleTransitionEnd
    }, /*#__PURE__*/ React.createElement(LeftAnimationWrapper, {
        ref: leftAnimationWrapperRef
    }), /*#__PURE__*/ React.createElement(DotWrapper, {
        ref: dotWrapperRef,
        className: cls(hiddenDotsLeft && classes.availableDotsLeft, hiddenDotsRight && classes.availableDotsRight)
    }, Array(visibleCount).fill(0).map(function(_, i) {
        return /*#__PURE__*/ React.createElement("div", {
            key: i,
            className: cls(classes.dot, i === activeIndex && classes.active),
            onClick: function onClick() {
                return handleClick(i);
            }
        });
    })), /*#__PURE__*/ React.createElement(RightAnimationWrapper, {
        ref: rightAnimationWrapperRef
    })));
});
