import React, { useEffect, useRef, useState } from 'react';
import cx from 'classnames';
import { Tooltip } from '../tooltip';
import type { ComponentBaseProps, DatadogContentPrivacy } from '../../types';
import type { TooltipProps } from '../tooltip';

const CLASS_NAME = 'TruncatedText';

export interface TruncatedTextProps extends ComponentBaseProps {
    className?: string;

    style?: React.CSSProperties;

    testId?: string;

    text: string;

    maxWidth?: number | string;

    /**
     * Use to enable breaking lines over multiple lines while still supporting text-overflow: ellipsis
     */
    numberOfLines?: number;

    /**
     * Sets the content privacy.
     */
    contentPrivacy?: DatadogContentPrivacy;

    /**
     * Props passed through to the Tooltip component.
     */
    tooltipProps?: Partial<TooltipProps>;
}

/**
 * TruncatedText is a wrapper around any string of text that allows truncation, either dynamically or using a fixed width.
 *
 * @type atom
 * @status live
 * @tags utilities
 */
export const TruncatedText = ({
    className,
    style,
    testId = CLASS_NAME,
    text,
    maxWidth,
    numberOfLines,
    contentPrivacy,
    tooltipProps,
}: TruncatedTextProps) => {
    const textRef = useRef<HTMLDivElement>(null);
    const [showTooltip, setShowTooltip] = useState<false | undefined>();

    useEffect(() => {
        const { current: textElement } = textRef;
        if (!textElement) return;

        const handleResize = () => {
            const isTruncated =
                textElement.offsetWidth < textElement.scrollWidth ||
                textElement.offsetHeight < textElement.scrollHeight;

            setShowTooltip(isTruncated ? undefined : false);
        };

        const observer = window.ResizeObserver && new window.ResizeObserver(handleResize);
        observer?.observe(textElement);

        handleResize();

        return () => {
            observer?.disconnect();
        };
    }, []);

    return (
        <Tooltip
            className={cx(CLASS_NAME, className, {
                dynamic: !maxWidth,
                'multi-line': numberOfLines,
            })}
            testId={testId}
            id={CLASS_NAME}
            show={showTooltip}
            message={text}
            style={{ maxWidth }}
            contentPrivacy={contentPrivacy}
            {...tooltipProps}
        >
            <div
                className={`${CLASS_NAME}-inner`}
                data-dd-privacy={contentPrivacy}
                ref={textRef}
                style={{ maxWidth, WebkitLineClamp: numberOfLines, ...style }}
            >
                {text}
            </div>
        </Tooltip>
    );
};
