"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _utils = require("../../utils");
var _react = require("react");
var _classnames = _interopRequireDefault(require("classnames"));
var _reactMeasure = _interopRequireDefault(require("react-measure"));
var _constants = require("../../constants");
var _Icon = _interopRequireDefault(require("../Icon"));
var _jsxRuntime = require("react/jsx-runtime");
// Copyright 1999-2023. Plesk International GmbH. All rights reserved.

const calcWidths = node => {
  const slideWidths = [].map.call(node.childNodes, el => el.getBoundingClientRect().width);
  const totalWidth = slideWidths.reduce((prev, curr) => prev + curr, 0);
  return {
    slideWidths,
    totalWidth
  };
};
/**
 * Carousel component is used for optimizing page space by displaying only some parts
 * of entire content in a cyclic view.
 * @since 0.0.42
 */
class Carousel extends _react.Component {
  constructor() {
    var _this;
    super(...arguments);
    _this = this;
    (0, _defineProperty2.default)(this, "state", {
      showControls: false,
      current: 0,
      next: 0,
      moving: false,
      slideWidths: [],
      totalWidth: 0
    });
    (0, _defineProperty2.default)(this, "speed", 500);
    (0, _defineProperty2.default)(this, "isRtl", void 0);
    (0, _defineProperty2.default)(this, "playTimer", null);
    (0, _defineProperty2.default)(this, "movingCallback", null);
    (0, _defineProperty2.default)(this, "rootRef", /*#__PURE__*/(0, _react.createRef)());
    (0, _defineProperty2.default)(this, "genuineRef", /*#__PURE__*/(0, _react.createRef)());
    (0, _defineProperty2.default)(this, "handlePrevClick", () => {
      this.stop();
      this.setCurrentSlide(this.state.current - 1);
    });
    (0, _defineProperty2.default)(this, "handleNextClick", () => {
      this.stop();
      this.setCurrentSlide(this.state.current + 1);
    });
    (0, _defineProperty2.default)(this, "play", () => {
      this.playTimer = setTimeout(() => {
        this.setCurrentSlide(this.state.current + 1);
        this.play();
      }, this.props.autoplayInterval);
    });
    (0, _defineProperty2.default)(this, "stop", () => {
      if (this.playTimer) {
        clearTimeout(this.playTimer);
        this.playTimer = null;
      }
    });
    (0, _defineProperty2.default)(this, "handleResize", _ref => {
      let {
        bounds
      } = _ref;
      const node = this.genuineRef.current;
      if (!node) {
        return;
      }
      const {
        slideWidths,
        totalWidth
      } = calcWidths(node);
      this.setState({
        slideWidths,
        totalWidth,
        showControls: (bounds?.width || 0) < totalWidth
      });
    });
    (0, _defineProperty2.default)(this, "getChildrenCount", () => {
      const {
        children
      } = this.props;
      return Array.isArray(children) ? children?.reduce((prev, curr) => Array.isArray(curr) ? prev + curr.length : prev + 1, 0) : 0;
    });
    (0, _defineProperty2.default)(this, "renderNavigationDots", () => {
      const {
        baseClassName,
        dots,
        items
      } = this.props;
      if (!dots || !items) {
        return null;
      }
      const {
        current
      } = this.state;
      const childrenCount = this.getChildrenCount();
      if (childrenCount <= 1) {
        return null;
      }
      return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
        className: `${baseClassName}__dots`,
        children: Array.from({
          length: childrenCount
        }).map((_, idx) => /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
          role: "button",
          className: (0, _classnames.default)(`${baseClassName}__dot`, current === idx ? `${baseClassName}__dot--current` : null),
          "aria-current": current === idx,
          onClick: () => this.setCurrentSlide(idx)
          // eslint-disable-next-line react/no-array-index-key
          ,
          children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
            name: "dot-big"
          })
        }, idx))
      });
    });
    (0, _defineProperty2.default)(this, "renderNavigationArrows", () => {
      const {
        baseClassName,
        arrows
      } = this.props;
      const {
        showControls
      } = this.state;
      if (!arrows || !showControls) {
        return null;
      }
      return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
        className: `${baseClassName}__controls`,
        children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
          type: "button",
          "aria-label": "previous slide",
          className: (0, _classnames.default)(`${baseClassName}__control`, `${baseClassName}__control--previous`),
          onClick: this.handlePrevClick,
          children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
            name: "chevron-left",
            flipHorizontal: this.isRtl,
            className: `${baseClassName}__control-icon`
          })
        }), /*#__PURE__*/(0, _jsxRuntime.jsx)("button", {
          type: "button",
          "aria-label": "next slide",
          className: (0, _classnames.default)(`${baseClassName}__control`, `${baseClassName}__control--next`),
          onClick: this.handleNextClick,
          children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
            name: "chevron-right",
            flipHorizontal: this.isRtl,
            className: `${baseClassName}__control-icon`
          })
        })]
      });
    });
    (0, _defineProperty2.default)(this, "renderSliderItems", function () {
      let showCurrent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      const {
        children,
        baseClassName,
        items
      } = _this.props;
      const {
        current
      } = _this.state;
      const childrenCount = _this.getChildrenCount();
      let width = '';
      if (items) {
        width = `${Math.ceil(100 / Math.min(childrenCount, items))}%`;
      }
      return _react.Children.map(children, (item, idx) => item && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
        className: (0, _classnames.default)(`${baseClassName}__item`, showCurrent && idx === current ? `${baseClassName}__item--current` : null),
        style: {
          width
        },
        children: item
      }));
    });
  }
  componentDidMount() {
    this.isRtl = (0, _utils.isRtl)();
    if (this.props.autoplay) {
      this.play();
    }
  }
  componentDidUpdate(prevProps) {
    if (!this.rootRef.current || !this.genuineRef.current) {
      return;
    }
    if (prevProps.autoplay !== this.props.autoplay) {
      this.props.autoplay ? this.play() : this.stop();
    }
  }
  componentWillUnmount() {
    this.stop();
    if (this.movingCallback) {
      clearTimeout(this.movingCallback);
    }
  }
  setCurrentSlide(next) {
    const {
      slideWidths,
      moving
    } = this.state;
    if (moving) {
      return;
    }
    let current = next;
    if (current < 0) {
      current = slideWidths.length - 1;
    }
    if (current >= slideWidths.length) {
      current = 0;
    }
    this.props.onSlide?.(current);
    this.setState({
      current,
      next,
      moving: true
    });
    this.movingCallback = setTimeout(() => {
      this.movingCallback = null;
      this.setState({
        moving: false
      });
    }, this.speed);
  }
  listStyle() {
    const {
      arrows
    } = this.props;
    const {
      current,
      next,
      moving,
      slideWidths,
      totalWidth
    } = this.state;
    const moveTo = moving ? next : current;
    let x = -totalWidth;

    // navigation arrows width
    if (arrows) {
      x += 26;
    }
    if (moveTo < 0) {
      for (let i = moveTo; i < 0; i++) {
        x += slideWidths[i + slideWidths.length];
      }
    } else {
      for (let i = 0; i < moveTo; i++) {
        x -= slideWidths[i % slideWidths.length];
      }
    }
    if (this.isRtl) {
      x = -x;
    }
    return {
      WebkitTransform: `translateX(${x ? `${x}px` : 0})`,
      transform: `translateX(${x ? `${x}px` : 0})`,
      WebkitTransition: moving ? `-webkit-transform ${this.speed}ms ease` : undefined,
      transition: moving ? `transform ${this.speed}ms ease` : undefined
    };
  }
  render() {
    const {
      showControls
    } = this.state;
    const {
      baseClassName,
      className,
      children,
      autoplay,
      autoplayInterval,
      items,
      onSlide,
      dots,
      arrows,
      ...props
    } = this.props;
    return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactMeasure.default, {
      onResize: this.handleResize,
      bounds: true,
      innerRef: this.rootRef,
      children: _ref2 => {
        let {
          measureRef
        } = _ref2;
        return /*#__PURE__*/(0, _jsxRuntime.jsxs)("section", {
          ref: measureRef,
          className: (0, _classnames.default)(baseClassName, className),
          ...props,
          children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
            className: `${baseClassName}__wrap`,
            children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
              className: `${baseClassName}__slides`,
              style: showControls ? this.listStyle() : undefined,
              children: [showControls && this.renderSliderItems(), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
                className: `${baseClassName}__genuine-slides`,
                ref: this.genuineRef,
                children: this.renderSliderItems(true)
              }), showControls && this.renderSliderItems()]
            }), this.renderNavigationArrows()]
          }), this.renderNavigationDots()]
        });
      }
    });
  }
}
(0, _defineProperty2.default)(Carousel, "defaultProps", {
  children: null,
  arrows: true,
  dots: false,
  autoplay: true,
  autoplayInterval: 5000,
  onSlide: null,
  className: null,
  baseClassName: `${_constants.CLS_PREFIX}carousel`
});
var _default = exports.default = Carousel;