import { useMemo, useState, useEffect } from 'react';
import throttle from 'lodash/throttle';
import numberOrUndefined from './numberOrUndefined';
const BUILT_IN_PADDING = 16;

/**
 * Hook to keep track of the appropriate top and left coordinates of a hovering
 * tooltip. The best tooltip position is determined based on the quadrant of
 * the screen that contains the cursor:
 *
 * - top left will put the tooltip below and to the right of the cursor
 * - top right will put the tooltip below and to the left of the cursor
 * - bottom left will put the tooltip above and to the right of the cursor
 * - bottom right will put the tooltip above and to the left of the cursor
 */
export default function useTooltipPosition({
  childNode,
  active
}) {
  const [{
    x: mouseX,
    y: mouseY
  }, setMousePosition] = useState({});
  const mousePositionCallback = useMemo(() => {
    const cbFunc = e => {
      const {
        x,
        y
      } = e;
      setMousePosition({
        x,
        y
      });
    };
    return throttle(cbFunc, 10);
  }, [setMousePosition]);
  useEffect(() => {
    window.document.addEventListener('mousemove', mousePositionCallback, false);
    return () => {
      window.document.removeEventListener('mousemove', mousePositionCallback, false);
    };
  }, [active, mousePositionCallback]);
  return useMemo(() => {
    if (!!active && typeof window !== 'undefined' && childNode.current) {
      const {
        innerWidth: windowWidth,
        innerHeight: windowHeight
      } = window;
      const {
        clientHeight: nodeHeight,
        clientWidth: nodeWidth
      } = childNode.current;
      const anchorY = mouseY > windowHeight / 2 ? 'bottom' : 'top';
      const top = anchorY === 'bottom' ? mouseY - nodeHeight - BUILT_IN_PADDING : mouseY + BUILT_IN_PADDING;
      const anchorX = mouseX > windowWidth / 2 ? 'right' : 'left';
      const left = anchorX === 'right' ? mouseX - nodeWidth - BUILT_IN_PADDING : mouseX + BUILT_IN_PADDING;
      return [numberOrUndefined(left), numberOrUndefined(top)];
    }
    return [];
  }, [active, mouseX, mouseY]);
}