import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { mapToCssModules } from './Shared/helper.js';
import CCarouselItem from './CCarouselItem';

export var Context = React.createContext({});

//component - CoreUI / CCarouselCustom

var CCarouselCustom = function CCarouselCustom(props) {
  var className = props.className,
      cssModule = props.cssModule,
      innerRef = props.innerRef,
      slide = props.slide;

  var _useState = useState("right"),
      direction = _useState[0],
      setDirection = _useState[1];

  var _useState2 = useState(false),
      indicatorClicked = _useState2[0],
      setIndicatorClicked = _useState2[1];

  var fields = useRef({ lastProps: null }).current;

  var setInterval = function setInterval() {
    var properties = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : props;

    clearInterval();
    if (properties.interval) {
      fields.cycleInterval = window.setInterval(function () {
        properties.next();
      }, parseInt(properties.interval, 10));
    }
  };

  var clearInterval = function clearInterval() {
    window.clearInterval(fields.cycleInterval);
  };

  var hoverStart = function hoverStart() {
    if (props.pause === 'hover') {
      clearInterval();
    }
    if (props.mouseEnter) {
      props.mouseEnter.apply(props, arguments);
    }
  };

  var hoverEnd = function hoverEnd() {
    if (props.pause === 'hover') {
      setInterval();
    }
    if (props.mouseLeave) {
      props.mouseLeave.apply(props, arguments);
    }
  };

  var handleKeyPress = function handleKeyPress(e) {
    if (props.keyboard) {
      if (e.keyCode === 37) {
        props.previous();
      } else if (e.keyCode === 39) {
        props.next();
      }
    }
  };

  var renderItems = function renderItems(carouselItems, className) {
    var slide = props.slide;

    return React.createElement(
      'div',
      { role: 'listbox', className: className },
      carouselItems.map(function (item, index) {
        var isIn = index === props.activeIndex;
        return React.cloneElement(item, {
          in: isIn,
          slide: slide
        });
      })
    );
  };

  var setState = function setState(oVal, nVal, setF) {
    if (nVal === oVal) return;
    setF(nVal);
  };

  //effect

  useEffect(function () {
    if (props.ride === 'carousel') {
      setInterval();
    }
    document.addEventListener('keyup', handleKeyPress);
    fields._handleKeyPress = handleKeyPress;
    return function cleanup() {
      clearInterval();
      document.removeEventListener('keyup', fields._handleKeyPress);
    };
  }, []);

  useEffect(function () {
    if (fields.wrappedOnClickFunc) {
      fields.wrappedOnClickFunc();
      setIndicatorClicked(false);
      fields.wrappedOnClickFunc = null;
    }
  });

  //render

  setInterval(props);
  if (fields.lastProps) {
    if (fields.lastProps.activeIndex + 1 === props.activeIndex) {
      setState(direction, "right", setDirection);
    } else if (fields.lastProps.activeIndex - 1 === props.activeIndex) {
      setState(direction, "left", setDirection);
    } else if (fields.lastProps.activeIndex > props.activeIndex) {
      setState(direction, indicatorClicked ? "left" : "right", setDirection);
    } else if (fields.lastProps.activeIndex !== props.activeIndex) {
      setState(direction, indicatorClicked ? "right" : "left", setDirection);
    }
    setState(indicatorClicked, false, setIndicatorClicked);
  }

  fields.lastProps = props;

  var outerClasses = mapToCssModules(classNames(className, 'carousel', slide && 'slide'), cssModule);
  var innerClasses = mapToCssModules(classNames('carousel-inner'), cssModule);

  var children = props.children.filter(function (child) {
    return child !== null && child !== undefined && typeof child !== 'boolean';
  });

  var slidesOnly = children.every(function (child) {
    return child.type === CCarouselItem;
  });

  if (slidesOnly) {
    return React.createElement(
      Context.Provider,
      { value: { direction: direction } },
      React.createElement(
        'div',
        { className: outerClasses, onMouseEnter: hoverStart, onMouseLeave: hoverEnd, ref: innerRef },
        renderItems(children, innerClasses)
      )
    );
  }

  if (children[0] instanceof Array) {
    var _carouselItems = children[0];
    var _controlLeft = children[1];
    var _controlRight = children[2];

    return React.createElement(
      Context.Provider,
      { value: { direction: direction } },
      React.createElement(
        'div',
        { className: outerClasses, onMouseEnter: hoverStart, onMouseLeave: hoverEnd, ref: innerRef },
        renderItems(_carouselItems, innerClasses),
        _controlLeft,
        _controlRight
      )
    );
  }

  var indicators = children[0];
  var wrappedOnClick = function wrappedOnClick(e) {
    if (typeof indicators.props.onClickHandler === 'function') {
      //this.setState({ indicatorClicked: true }, () => indicators.props.onClickHandler(e));
      fields.wrappedOnClickFunc = function () {
        return indicators.props.onClickHandler(e);
      };
      setIndicatorClicked(true);
    }
  };

  var wrappedIndicators = React.cloneElement(indicators, { onClickHandler: wrappedOnClick });
  var carouselItems = children[1];
  var controlLeft = children[2];
  var controlRight = children[3];

  return React.createElement(
    Context.Provider,
    { value: { direction: direction } },
    React.createElement(
      'div',
      { className: outerClasses, onMouseEnter: hoverStart, onMouseLeave: hoverEnd, ref: innerRef },
      wrappedIndicators,
      renderItems(carouselItems, innerClasses),
      controlLeft,
      controlRight
    )
  );
};

CCarouselCustom.propTypes = process.env.NODE_ENV !== "production" ? {
  cssModule: PropTypes.object,
  className: PropTypes.string,
  children: PropTypes.array,
  //
  innerRef: PropTypes.oneOfType([PropTypes.object, PropTypes.func, PropTypes.string]),
  activeIndex: PropTypes.number,
  next: PropTypes.func.isRequired,
  previous: PropTypes.func.isRequired,
  keyboard: PropTypes.bool,
  pause: PropTypes.oneOf(['hover', false]),
  ride: PropTypes.oneOf(['carousel']),
  interval: PropTypes.oneOfType([PropTypes.number, PropTypes.string, PropTypes.bool]),
  mouseEnter: PropTypes.func,
  mouseLeave: PropTypes.func,
  slide: PropTypes.bool
} : {};

CCarouselCustom.defaultProps = {
  interval: 5000,
  pause: 'hover',
  keyboard: true,
  slide: true
};

export default CCarouselCustom;