var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

import React, { useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import CPopperContent from './CPopperContent';
import { getTarget, targetPropType, omit, PopperPlacements, mapToCssModules, DOMElement } from './Shared/helper.js';

// global

var DEFAULT_DELAYS = {
  show: 0,
  hide: 250
};

var isInDOMSubtree = function isInDOMSubtree(element, subtreeRoot) {
  return subtreeRoot && (element === subtreeRoot || subtreeRoot.contains(element));
};

//component - CoreUI / CTooltipPopoverWrapper

var CTooltipPopoverWrapper = function CTooltipPopoverWrapper(props) {
  var _extends2;

  var className = props.className,
      cssModule = props.cssModule,
      innerRef = props.innerRef,
      innerClassName = props.innerClassName,
      target = props.target,
      isOpen = props.show,
      hideArrow = props.hideArrow,
      boundariesElement = props.boundariesElement,
      placement = props.placement,
      placementPrefix = props.placementPrefix,
      arrowClassName = props.arrowClassName,
      container = props.container,
      modifiers = props.modifiers,
      offset = props.offset;


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

  var onMouseOverTooltipContent = function onMouseOverTooltipContent() {
    if (fields.trigger.indexOf('hover') > -1 && !fields.autohide) {
      if (fields._hideTimeout) {
        clearHideTimeout();
      }
    }
  };

  var onMouseLeaveTooltipContent = function onMouseLeaveTooltipContent(e) {
    if (fields.trigger.indexOf('hover') > -1 && !fields.autohide) {
      if (fields._showTimeout) {
        clearShowTimeout();
      }
      e.persist();
      fields._hideTimeout = setTimeout(function () {
        return hide(e);
      }, getDelay('hide'));
    }
  };

  var onEscKeyDown = function onEscKeyDown(e) {
    if (e.key === 'Escape') {
      hide(e);
    }
  };

  var getRef = function getRef(ref) {
    var innerRef = props.innerRef;

    if (innerRef) {
      if (typeof innerRef === 'function') {
        innerRef(ref);
      } else if ((typeof innerRef === 'undefined' ? 'undefined' : _typeof(innerRef)) === 'object') {
        innerRef.current = ref;
      }
    }
    fields._popover = ref;
  };

  var getDelay = function getDelay(key) {
    if (_typeof(fields.delay) === 'object') {
      return isNaN(fields.delay[key]) ? DEFAULT_DELAYS[key] : fields.delay[key];
    }
    return fields.delay;
  };

  var show = function show(e) {
    if (!fields.isOpen) {
      clearShowTimeout();
      toggle(e);
    }
  };

  var showWithDelay = function showWithDelay(e) {
    if (fields._hideTimeout) {
      clearHideTimeout();
    }
    fields._showTimeout = setTimeout(function () {
      return show(e);
    }, getDelay('show'));
  };

  var hide = function hide(e) {
    if (fields.isOpen) {
      clearHideTimeout();
      toggle(e);
    }
  };

  var hideWithDelay = function hideWithDelay(e) {
    if (fields._showTimeout) {
      clearShowTimeout();
    }
    fields._hideTimeout = setTimeout(function () {
      return hide(e);
    }, getDelay('hide'));
  };

  var clearShowTimeout = function clearShowTimeout() {
    clearTimeout(fields._showTimeout);
    fields._showTimeout = undefined;
  };

  var clearHideTimeout = function clearHideTimeout() {
    clearTimeout(fields._hideTimeout);
    fields._hideTimeout = undefined;
  };

  var handleDocumentClick = function handleDocumentClick(e) {
    var triggers = fields.trigger.split(' ');
    if (triggers.indexOf('legacy') > -1 && (fields.isOpen || isInDOMSubtree(e.target, fields._target))) {
      if (fields._hideTimeout) {
        clearHideTimeout();
      }
      if (fields.isOpen && !isInDOMSubtree(e.target, fields._popover)) {
        hideWithDelay(e);
      } else {
        showWithDelay(e);
      }
    } else if (triggers.indexOf('click') > -1 && isInDOMSubtree(e.target, fields._target)) {
      if (fields._hideTimeout) {
        clearHideTimeout();
      }
      if (!fields.isOpen) {
        showWithDelay(e);
      } else {
        hideWithDelay(e);
      }
    }
  };

  var addTargetEvents = function addTargetEvents() {
    if (props.trigger) {
      var triggers = props.trigger.split(' ');
      if (triggers.indexOf('manual') === -1) {
        if (triggers.indexOf('click') > -1 || triggers.indexOf('legacy') > -1) {
          ['click', 'touchstart'].forEach(function (event) {
            return document.addEventListener(event, handleDocumentClick, true);
          });
          fields._handleDocumentClick = handleDocumentClick;
        }

        if (fields._target) {
          if (triggers.indexOf('hover') > -1) {
            fields._target.addEventListener('mouseover', showWithDelay, true);
            fields._target.addEventListener('mouseout', hideWithDelay, true);
            fields._showWithDelay = showWithDelay;
            fields._hideWithDelay = hideWithDelay;
          }
          if (triggers.indexOf('focus') > -1) {
            fields._target.addEventListener('focusin', show, true);
            fields._target.addEventListener('focusout', hide, true);
            fields._show = show;
            fields._hide = hide;
          }
          fields._target.addEventListener('keydown', onEscKeyDown, true);
          fields._onEscKeyDown = onEscKeyDown;
        }
      }
    }
  };

  var removeTargetEvents = function removeTargetEvents() {

    if (fields._target) {
      fields._target.removeEventListener('mouseover', fields._showWithDelay, true);
      fields._target.removeEventListener('mouseout', fields._hideWithDelay, true);
      fields._target.removeEventListener('keydown', fields._onEscKeyDown, true);
      fields._target.removeEventListener('focusin', fields._show, true);
      fields._target.removeEventListener('focusout', fields._hide, true);
    }

    ['click', 'touchstart'].forEach(function (event) {
      return document.removeEventListener(event, fields._handleDocumentClick, true);
    });
  };

  var updateTarget = function updateTarget() {
    var newTarget = getTarget(props.target);
    if (newTarget !== fields._target) {
      removeTargetEvents();
      fields._target = newTarget;
      addTargetEvents();
    }
  };

  var toggle = function toggle(e) {
    if (fields.disabled) {
      return e && e.preventDefault();
    }
    return fields.toggle(e);
  };

  //effect
  useEffect(function () {
    updateTarget();
    return function cleanup() {
      removeTargetEvents();
    };
  }, []);

  //render

  fields.isOpen = props.show;
  fields.autohide = props.autohide;
  fields.trigger = props.trigger;
  fields.delay = props.delay;
  fields.toggle = props.toggle;
  fields.disabled = props.disabled;

  if (!props.show) {
    return null;
  }

  updateTarget();

  var attributes = omit(props, Object.keys(CTooltipPopoverWrapper.propTypes));
  var popperClasses = mapToCssModules(className, cssModule);
  var classes = mapToCssModules(innerClassName, cssModule);

  return React.createElement(
    CPopperContent,
    {
      className: popperClasses,
      target: target,
      show: isOpen,
      hideArrow: hideArrow,
      boundariesElement: boundariesElement,
      placement: placement,
      placementPrefix: placementPrefix,
      arrowClassName: arrowClassName,
      container: container,
      modifiers: modifiers,
      offset: offset,
      cssModule: cssModule
    },
    React.createElement('div', _extends({}, attributes, (_extends2 = {
      ref: getRef,
      className: classes,
      role: 'tooltip',
      'aria-hidden': isOpen,
      onMouseOver: onMouseOverTooltipContent,
      onMouseLeave: onMouseLeaveTooltipContent,
      onKeyDown: onEscKeyDown
    }, _extends2['ref'] = innerRef, _extends2)))
  );
};

CTooltipPopoverWrapper.propTypes = process.env.NODE_ENV !== "production" ? {
  className: PropTypes.string,
  cssModule: PropTypes.object,
  //
  innerRef: PropTypes.oneOfType([PropTypes.object, PropTypes.func, PropTypes.string]),
  placement: PropTypes.oneOf(PopperPlacements),
  target: targetPropType.isRequired,
  container: targetPropType,
  show: PropTypes.bool,
  disabled: PropTypes.bool,
  hideArrow: PropTypes.bool,
  boundariesElement: PropTypes.oneOfType([PropTypes.string, DOMElement]),
  innerClassName: PropTypes.string,
  arrowClassName: PropTypes.string,
  toggle: PropTypes.func,
  autohide: PropTypes.bool,
  placementPrefix: PropTypes.string,
  delay: PropTypes.oneOfType([PropTypes.shape({ show: PropTypes.number, hide: PropTypes.number }), PropTypes.number]),
  modifiers: PropTypes.object,
  offset: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  trigger: PropTypes.string
} : {};

CTooltipPopoverWrapper.defaultProps = {
  show: false,
  hideArrow: false,
  autohide: false,
  delay: DEFAULT_DELAYS,
  toggle: function toggle() {},
  trigger: 'click'
};

export default CTooltipPopoverWrapper;