import {
    ReactNode,
    ComponentPropsWithRef,
    forwardRef,
    ForwardedRef,
    Key,
} from 'react';
import { Provider, Root, Trigger, Content } from '@radix-ui/react-tooltip';
import { Portal } from '../Portal';

import { styled, theme } from '../../stitches.config';

const StyledTooltipContent = styled(Content, {
    backgroundColor: theme.colors['transparent-dark-2'],
    color: 'white',
    borderRadius: theme.radii.default,
    padding: `${theme.space[1]} ${theme.space[2]}`,
    zIndex: '30',
});

export interface TooltipProps extends ComponentPropsWithRef<'div'> {
    /** Tooltip Trigger  */
    children: ReactNode;

    /** Content to show in the tooltip */
    content: ReactNode;

    /** Key passed to the content that will force a rerender when it changes */
    contentKey?: Key | null;

    /** Boolean to control the state of the tooltip */
    open?: boolean;

    /** Callback that is triggered when the tooltip is opened */
    onOpen?: () => void;

    /** Callback that is triggered when the tooltip is closed */
    onClose?: () => void;

    /** Side where the content is position (relative to the trigger)  */
    side?: 'top' | 'right' | 'bottom' | 'left';

    /** Pixel distance the Tooltip is away from the side  */
    offset?: number;

    /** Alignment of the content (relative to the trigger)  */
    align?: 'start' | 'center' | 'end';

    /** Container to append the tooltip to */
    container?: HTMLElement | null;
}

/**
 * Tooltip component
 */

export const _Tooltip = (
    props: TooltipProps,
    ref: ForwardedRef<HTMLDivElement>,
): JSX.Element => {
    const {
        children,
        content,
        contentKey,
        open,
        onOpen = () => null,
        onClose = () => null,
        side,
        offset = 4,
        align,
        container,
        ...otherProps
    } = props;
    return (
        <Provider>
            <Root
                open={open}
                onOpenChange={(open: boolean) => {
                    if (open) {
                        onOpen();
                    } else {
                        onClose();
                    }
                }}
            >
                <Trigger asChild={true}>{children}</Trigger>
                <Portal container={container}>
                    <StyledTooltipContent
                        sideOffset={offset}
                        ref={ref}
                        side={side}
                        align={align}
                        key={contentKey}
                        {...otherProps}
                    >
                        {content}
                    </StyledTooltipContent>
                </Portal>
            </Root>
        </Provider>
    );
};

export const Tooltip = forwardRef(_Tooltip) as (
    props: TooltipProps & {
        ref?: ForwardedRef<HTMLDivElement>;
    },
) => ReturnType<typeof _Tooltip>;
