import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["children", "className", "documentObject", "tooltip", "tooltipColor", "onTooltipEntered", "tooltipHideOnClick", "tooltipIcon", "tooltipPosition", "tooltipShowOnClick", "tooltipSize", "tooltipShowDelay", "zIndex", "onClick", "onMouseEnter", "onMouseLeave", "tooltipActive", "ComposedComponent"];

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

import uiUtilities from '@teamleader/ui-utilities';
import cx from 'classnames';
import omit from 'lodash.omit';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';
import Transition from 'react-transition-group/Transition';
import Box from '../box';
import DocumentObjectProvider, { Context as DocumentObjectContext } from '../hoc/DocumentObjectProvider';
import { getViewport } from '../utils/utils';
import theme from './theme.css';
export var POSITIONS = {
  BOTTOM: 'bottom',
  HORIZONTAL: 'horizontal',
  LEFT: 'left',
  RIGHT: 'right',
  TOP: 'top',
  VERTICAL: 'vertical'
};
var SIZE_MAP = {
  large: {
    padding: 4
  },
  medium: {
    padding: 3
  },
  small: {
    paddingHorizontal: 3,
    paddingVertical: 2
  }
};

var TooltippedComponent = function TooltippedComponent(_ref) {
  var children = _ref.children,
      className = _ref.className,
      documentObject = _ref.documentObject,
      tooltip = _ref.tooltip,
      _ref$tooltipColor = _ref.tooltipColor,
      tooltipColor = _ref$tooltipColor === void 0 ? 'white' : _ref$tooltipColor,
      onTooltipEntered = _ref.onTooltipEntered,
      _ref$tooltipHideOnCli = _ref.tooltipHideOnClick,
      tooltipHideOnClick = _ref$tooltipHideOnCli === void 0 ? true : _ref$tooltipHideOnCli,
      _ref$tooltipIcon = _ref.tooltipIcon,
      tooltipIcon = _ref$tooltipIcon === void 0 ? null : _ref$tooltipIcon,
      _ref$tooltipPosition = _ref.tooltipPosition,
      tooltipPosition = _ref$tooltipPosition === void 0 ? 'top' : _ref$tooltipPosition,
      _ref$tooltipShowOnCli = _ref.tooltipShowOnClick,
      tooltipShowOnClick = _ref$tooltipShowOnCli === void 0 ? false : _ref$tooltipShowOnCli,
      _ref$tooltipSize = _ref.tooltipSize,
      tooltipSize = _ref$tooltipSize === void 0 ? 'medium' : _ref$tooltipSize,
      _ref$tooltipShowDelay = _ref.tooltipShowDelay,
      tooltipShowDelay = _ref$tooltipShowDelay === void 0 ? 100 : _ref$tooltipShowDelay,
      _ref$zIndex = _ref.zIndex,
      zIndex = _ref$zIndex === void 0 ? 700 : _ref$zIndex,
      onClick = _ref.onClick,
      onMouseEnter = _ref.onMouseEnter,
      onMouseLeave = _ref.onMouseLeave,
      _ref$tooltipActive = _ref.tooltipActive,
      tooltipActive = _ref$tooltipActive === void 0 ? null : _ref$tooltipActive,
      ComposedComponent = _ref.ComposedComponent,
      other = _objectWithoutProperties(_ref, _excluded);

  var tooltipRoot = useMemo(function () {
    return documentObject.createElement('div');
  }, []);
  var ref = useRef(null);

  var _useState = useState(false),
      _useState2 = _slicedToArray(_useState, 2),
      active = _useState2[0],
      setActive = _useState2[1];

  var _useState3 = useState({
    position: tooltipPosition,
    top: 'auto',
    left: 'auto'
  }),
      _useState4 = _slicedToArray(_useState3, 2),
      position = _useState4[0],
      setPosition = _useState4[1];

  var activate = function activate(position) {
    documentObject.body.appendChild(tooltipRoot);
    setActive(true);
    setPosition({
      position: position.position,
      top: position.top,
      left: position.left
    });
  };

  var getPosition = function getPosition(element) {
    if (tooltipPosition === POSITIONS.HORIZONTAL) {
      var origin = element.getBoundingClientRect();

      var _getViewport = getViewport(),
          windowWidth = _getViewport.width;

      var toRight = origin.left < windowWidth / 2 - origin.width / 2;
      return toRight ? POSITIONS.RIGHT : POSITIONS.LEFT;
    } else if (tooltipPosition === POSITIONS.VERTICAL) {
      var _origin = element.getBoundingClientRect();

      var _getViewport2 = getViewport(),
          windowHeight = _getViewport2.height;

      var toBottom = _origin.top < windowHeight / 2 - _origin.height / 2;
      return toBottom ? POSITIONS.BOTTOM : POSITIONS.TOP;
    }

    return tooltipPosition;
  };

  var calculatePosition = function calculatePosition(element) {
    if (typeof (element === null || element === void 0 ? void 0 : element.getBoundingClientRect) !== 'function') {
      return {
        top: 0,
        left: 0,
        position: tooltipPosition
      };
    }

    var _element$getBoundingC = element.getBoundingClientRect(),
        top = _element$getBoundingC.top,
        left = _element$getBoundingC.left,
        height = _element$getBoundingC.height,
        width = _element$getBoundingC.width;

    var position = getPosition(element);
    var xOffset = window.scrollX || window.pageXOffset;
    var yOffset = window.scrollY || window.pageYOffset;

    if (position === POSITIONS.BOTTOM) {
      return {
        top: top + height + yOffset,
        left: left + width / 2 + xOffset,
        position: position
      };
    } else if (position === POSITIONS.TOP) {
      return {
        top: top + yOffset,
        left: left + width / 2 + xOffset,
        position: position
      };
    } else if (position === POSITIONS.LEFT) {
      return {
        top: top + height / 2 + yOffset,
        left: left + xOffset,
        position: position
      };
    } else if (position === POSITIONS.RIGHT) {
      return {
        top: top + height / 2 + yOffset,
        left: left + width + xOffset,
        position: position
      };
    }

    return {
      top: 0,
      left: 0,
      position: tooltipPosition
    };
  };

  var handleMouseEnter = function handleMouseEnter(event) {
    activate(calculatePosition(event.currentTarget));

    if (onMouseEnter) {
      onMouseEnter(event);
    }
  };

  var handleMouseLeave = function handleMouseLeave(event) {
    setActive(false);

    if (onMouseLeave) {
      onMouseLeave(event);
    }
  };

  var handleClick = function handleClick(event) {
    if (tooltipHideOnClick && active) {
      setActive(false);
    }

    if (tooltipShowOnClick && !active) {
      activate(calculatePosition(event.currentTarget));
    }

    if (onClick) {
      onClick(event);
    }
  };

  var handleTransitionExited = function handleTransitionExited() {
    documentObject.body.removeChild(tooltipRoot);
  };

  var handleTransitionEntered = function handleTransitionEntered() {
    onTooltipEntered && onTooltipEntered();
  };

  useEffect(function () {
    if (tooltipActive) {
      activate(calculatePosition(ref.current));
    }

    if (tooltipActive) {
      if (tooltipActive && !active) {
        activate(calculatePosition(ref.current));
      }

      if (!tooltipActive && active) {
        setActive(false);
      }
    }
  }, [tooltipActive, active]);
  var rest = omit(other, ['onTooltipEntered', 'tooltipHideOnClick', 'tooltipPosition', 'tooltipShowOnClick', 'tooltipShowDelay', 'documentObject']);

  var childProps = _objectSpread(_objectSpread({}, rest), {}, {
    className: className,
    onClick: onClick,
    onMouseEnter: onMouseEnter,
    onMouseLeave: onMouseLeave,
    ref: ref
  });

  if (tooltipActive === null) {
    childProps = _objectSpread(_objectSpread({}, childProps), {}, {
      onClick: handleClick,
      onMouseEnter: handleMouseEnter,
      onMouseLeave: handleMouseLeave
    });
  }

  return /*#__PURE__*/React.createElement(ComposedComponent, childProps, children, /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(Transition, {
    in: active,
    onExited: handleTransitionExited,
    onEntered: handleTransitionEntered,
    timeout: {
      enter: tooltipShowDelay,
      exit: 1000
    }
  }, function (state) {
    var _cx;

    var classNames = cx(uiUtilities['box-shadow-200'], theme['tooltip'], theme[tooltipColor], theme[tooltipSize], (_cx = {}, _defineProperty(_cx, theme['is-entering'], state === 'entering'), _defineProperty(_cx, theme['is-entered'], state === 'entered'), _defineProperty(_cx, theme['is-exiting'], state === 'exiting'), _defineProperty(_cx, theme[position.position], theme[position.position]), _cx));
    return /*#__PURE__*/React.createElement("div", {
      className: classNames,
      "data-teamleader-ui": "tooltip",
      style: {
        top: position.top,
        left: position.left,
        zIndex: zIndex
      }
    }, /*#__PURE__*/React.createElement(Box, _extends({
      className: theme['inner']
    }, SIZE_MAP[tooltipSize]), tooltipIcon && /*#__PURE__*/React.createElement("div", {
      className: theme['icon']
    }, tooltipIcon), /*#__PURE__*/React.createElement("div", {
      className: theme['text']
    }, tooltip)));
  }), tooltipRoot));
};

function Tooltip(ComposedComponent) {
  return DocumentObjectProvider(function (props) {
    return /*#__PURE__*/React.createElement(DocumentObjectContext.Consumer, null, function (documentObject) {
      return /*#__PURE__*/React.createElement(TooltippedComponent, _extends({}, props, {
        tooltip: props.tooltip,
        documentObject: documentObject,
        ComposedComponent: ComposedComponent
      }), props.children);
    });
  });
}

export default Tooltip;