import type { FC } from 'react';
import React, { useRef, useState } from 'react';
import { createHref } from '@theorchard/suite-frontend';
import { Link } from 'react-router-dom';
import { EMPTY_CHAR } from 'src/constants';
import TooltipWrapper from './tooltipWrapper';

export type Placement = 'top' | 'bottom' | 'right' | 'left';

export interface Props {
    value?: string;
    useLink?: boolean;
    route?: string;
    params?: Record<
        string,
        string | string[] | number | number[] | boolean | undefined | null
    >;
    maxLength?: number;
    placement?: Placement;
    onClick?: () => void;
    disableTooltipPointerEvents?: boolean;
}

export const CLASS_NAME = 'TruncatedText';
export const CLASS_NAME_DISABLE_POINTER = `${CLASS_NAME}-disable-pointer`;

const TruncatedText: FC<Props> = ({
    value,
    useLink,
    route,
    maxLength,
    params = {},
    placement = 'bottom',
    onClick,
    disableTooltipPointerEvents = false,
}) => {
    const [showTooltip, setShowTooltip] = useState(false);
    const target = useRef(null);

    const isValueOverflow = !!maxLength && !!value && value.length > maxLength;
    const text = isValueOverflow
        ? `${value?.substring(0, maxLength)}...`
        : value;

    const handleFocus = (element: HTMLElement) => {
        const isOverflowing = element.offsetWidth < element.scrollWidth;
        setShowTooltip(isOverflowing || isValueOverflow);
    };

    const handleBlur = () => setShowTooltip(false);

    return useLink && route ? (
        <Link
            className={CLASS_NAME}
            to={createHref(route, params)}
            ref={target}
            onClick={onClick}
            onMouseEnter={e => handleFocus(e.currentTarget)}
            onFocus={e => handleFocus(e.currentTarget)}
            onMouseLeave={handleBlur}
            onBlur={handleBlur}
        >
            {showTooltip ? (
                <TooltipWrapper
                    className={CLASS_NAME}
                    classNameDisablePointer={CLASS_NAME_DISABLE_POINTER}
                    value={value}
                    placement={placement}
                    disableTooltipPointerEvents={disableTooltipPointerEvents}
                >
                    {text}
                </TooltipWrapper>
            ) : (
                text
            )}
        </Link>
    ) : (
        <div
            className={CLASS_NAME}
            ref={target}
            onMouseEnter={e => handleFocus(e.currentTarget)}
            onFocus={e => handleFocus(e.currentTarget)}
            onMouseLeave={handleBlur}
            onBlur={handleBlur}
        >
            {showTooltip ? (
                <TooltipWrapper
                    className={CLASS_NAME}
                    classNameDisablePointer={CLASS_NAME_DISABLE_POINTER}
                    value={value}
                    placement={placement}
                    disableTooltipPointerEvents={disableTooltipPointerEvents}
                >
                    {text}
                </TooltipWrapper>
            ) : (
                text
            )}
        </div>
    );
};

export const GridTableTruncatedTextCell = (data: {
    value?: number | string | null;
}) => <TruncatedText value={data.value?.toString() || EMPTY_CHAR} />;

export default TruncatedText;
