import React, { useState, useRef, useLayoutEffect } from 'react';
import classNames from 'classnames';
import { Tooltip, TOOLTIP_DELAY_TYPES, TOOLTIP_PLACEMENT_TYPES } from '../tooltip';
import { jsx as _jsx } from "react/jsx-runtime";
const MIN_LINE_HEIGHT = 1.2;
/**
 * The component recognizes whether a text element is overflowed truncate it with CSS and provide full text in the tooltip.
 * - supports custom tooltip text with custom placement.
 * - supports only one element as children inside
 * - need provide any HTML element inside component like <span> or <p>.
 * 🚨 NOTE ➡️: max-width & min-width for a parent element is required for proper work. 🚨
 * */
const TruncateWithTooltip = ({
  children,
  tooltipPlacement = TOOLTIP_PLACEMENT_TYPES.TOP,
  tooltipText,
  tooltipId,
  tooltipDocsLink,
  tooltipDelayType = TOOLTIP_DELAY_TYPES.FAST,
  tooltipTestId,
  className,
  isDisabled = false
}) => {
  const [isTruncating, setTruncating] = useState(false);
  const [needLineHeight, setNeedLineHeight] = useState(false);
  const [contentText, setContentText] = useState(null);
  const elementRef = useRef();
  // NOTE: This solution has a potential issue with a pixel or two when the text is long enough and will be ellipsed,
  // but the tooltip is not shown. That happens due to pixel rounding of scrollWidth and clientWidth.
  // While getBoundingClientRect could give us a precise width, it will include padding and borders,
  // and scrollWidth will still be rounded. Thus, we might get many false positives and show a tooltip too many times.
  const doesTextFit = target => target.scrollWidth <= target.clientWidth && target.scrollHeight <= target.clientHeight;
  const updateOverflow = ({
    target
  }) => {
    if (tooltipText || isDisabled) {
      return;
    }
    if (!isTruncating && !doesTextFit(target)) {
      setContentText(target.textContent);
      return setTruncating(true);
    }
    if (isTruncating && doesTextFit(target)) {
      setContentText(null);
      return setTruncating(false);
    }
  };
  const updatedChildren = /*#__PURE__*/React.cloneElement(children, {
    className: classNames('truncate-with-tooltip', className, needLineHeight && 'with-line-height'),
    onMouseOver: updateOverflow,
    ref: elementRef
  });
  useLayoutEffect(() => {
    if (elementRef.current) {
      const {
        fontSize,
        lineHeight
      } = window.getComputedStyle(elementRef.current);
      const diff = parseFloat(lineHeight) / parseFloat(fontSize);
      // if line-height less then normal, scroll height will be more then clientHeight
      if (MIN_LINE_HEIGHT > diff) {
        setNeedLineHeight(true);
      }
    }
  }, []);
  return !isDisabled && (isTruncating || tooltipText) ? /*#__PURE__*/_jsx(Tooltip, {
    testId: tooltipTestId,
    content: tooltipText ?? contentText,
    docsLink: tooltipDocsLink,
    placement: tooltipPlacement,
    delayType: tooltipDelayType,
    tooltipId: tooltipId,
    children: updatedChildren
  }) : updatedChildren;
};
export default TruncateWithTooltip;