import React, { ReactNode, useEffect, useRef, useState } from 'react';
import './Tooltip.scss';
import { createPortal } from 'react-dom';
interface Styles {
  [key: string]: {
    top?: number;
    left?: number;
    right?: number;
  };
}
export interface TooltipProps {
  title: string;
  children: React.ReactNode;
  placement?:
    | 'bottom'
    | 'left'
    | 'right'
    | 'top'
    | 'top-start'
    | 'top-end'
    | 'bottom-start'
    | 'bottom-end';
  disabled?: boolean;
}
const Tooltip: React.FC<TooltipProps> = ({
  title,
  children,
  placement = 'bottom',
  disabled = false,
}) => {
  const [isVisible, setIsVisible] = useState(false);
  const titleRef = useRef<HTMLDivElement>(null);
  const [tooltipContainerPosition, settooltipContainerPosition] = useState({
    posX: 0,
    fromRight: 0,
    posY: 0,
    width: 0,
    fromBottom: 0,
  });
  const [titleDimensions, setTitleDimensions] = useState({
    height: 0,
    width: 0,
  });
  const [childrenContainerHeight, setChildrenContainerHeight] = useState(0);

  const styles: Styles = {
    left: {
      top: tooltipContainerPosition.posY,
      left: tooltipContainerPosition.posX - titleDimensions.width - 5,
    },
    right: {
      top: tooltipContainerPosition.posY,
      left: tooltipContainerPosition.fromRight + 5,
    },
    top: {
      top: tooltipContainerPosition.posY - titleDimensions.height - 5,
      left:
        tooltipContainerPosition.posX -
        titleDimensions.width / 2 +
        tooltipContainerPosition.width / 2,
    },
    bottom: {
      top: tooltipContainerPosition.posY + childrenContainerHeight + 5,
      left:
        tooltipContainerPosition.posX -
        titleDimensions.width / 2 +
        tooltipContainerPosition.width / 2,
    },
    'top-start': {
      top: tooltipContainerPosition.posY - titleDimensions.height - 5,
      left: tooltipContainerPosition.posX,
    },
    'top-end': {
      top: tooltipContainerPosition.posY - titleDimensions.height - 5,
      left: tooltipContainerPosition.fromRight - titleDimensions.width,
    },
    'bottom-start': {
      top: tooltipContainerPosition.posY + childrenContainerHeight + 5,
      left: tooltipContainerPosition.posX,
    },
    'bottom-end': {
      top: tooltipContainerPosition.posY + childrenContainerHeight + 5,
      left: tooltipContainerPosition.fromRight - titleDimensions.width,
    },
  };
  const tooltipContainerRef = useRef<HTMLDivElement>(null);
  const handleScroll = () => {
    if (tooltipContainerRef.current) {
      setIsVisible(false);
    }
  };
  const nullCheckForTitle = (val: string) => {
    return val === undefined || val == null || val.length <= 0 ? true : false;
  };
  const handleClickAnywhere = () => {
    setIsVisible(false);
  };
  useEffect(() => {
    window.addEventListener('scroll', handleScroll);
    window.addEventListener('click', handleClickAnywhere);
    return () => {
      window.removeEventListener('scroll', handleScroll);
      window.removeEventListener('click', handleClickAnywhere);
    };
  }, []);

  const calculateDim = () => {
    if (tooltipContainerRef?.current) {
      const computedStyle = window.getComputedStyle(
        tooltipContainerRef.current
      );
      if (
        computedStyle.display === 'none' ||
        computedStyle.visibility === 'hidden' ||
        computedStyle.opacity === '0'
      ) {
        setIsVisible(false);
        return;
      }
    }
    if (titleRef?.current) {
      setTitleDimensions({
        height: titleRef.current.offsetHeight,
        width: titleRef.current.offsetWidth,
      });
    }

    if (tooltipContainerRef?.current && titleRef?.current) {
      const rect = tooltipContainerRef.current.getBoundingClientRect();
      setChildrenContainerHeight(rect.height);
      let leftSpaceAvailable =
        rect.left +
        window.scrollX +
        tooltipContainerRef.current.offsetWidth / 2 -
        titleRef.current.offsetWidth / 2;

      let rightSpaceAvailable =
        window.innerWidth -
        rect.right +
        tooltipContainerRef.current.offsetWidth / 2 -
        titleRef.current.offsetWidth / 2;
      let posX = rect.left + window.scrollX;
      if (leftSpaceAvailable < 0) {
        posX = posX - leftSpaceAvailable;
      }
      if (rightSpaceAvailable < 0) {
        posX = posX + rightSpaceAvailable;
      }
      settooltipContainerPosition({
        posX: posX,
        fromRight: rect.right,
        posY: rect.top,
        width: tooltipContainerRef.current.offsetWidth,
        fromBottom: window.innerHeight - tooltipContainerRef.current.offsetTop,
      });
    }
  };
  useEffect(() => {
    calculateDim();
  }, [isVisible]);
  const onMouseEnter = () => {
    setIsVisible(true);
  };
  const onMouseLeave = () => {
    setIsVisible(false);
  };
  return (
    <div
      ref={tooltipContainerRef}
      className="tooltip-container-ff"
      onMouseEnter={onMouseEnter}
      onMouseLeave={onMouseLeave}
    >
      {children}

      {isVisible &&
        !disabled &&
        !nullCheckForTitle(title) &&
        createPortal(
          <div
            ref={titleRef}
            style={{
              ...styles[placement],
              zIndex: 100000,
            }}
            className={`tooltip-ff ${isVisible && 'tooltip-ff--visible'}`}
          >
            {title}
          </div>,
          document.body
        )}
    </div>
  );
};

export default Tooltip;
