import { clsx } from '@trail-ui/shared-utils';
import type { PopoverSlots, PopoverVariantProps, SlotsToClasses } from '@trail-ui/theme';
import { popover } from '@trail-ui/theme';
import { ReactNode, useMemo } from 'react';
import type {
  TooltipProps as AriaTooltipProps,
  TooltipTriggerComponentProps,
} from 'react-aria-components';
import {
  Tooltip as AriaTooltip,
  TooltipTrigger as AriaTooltipTrigger,
  OverlayArrow,
} from 'react-aria-components';

export interface TooltipProps extends Omit<AriaTooltipProps, 'children'>, PopoverVariantProps {
  children?: ReactNode;
  /**
   * Whether the element should render an arrow.
   * @default false
   */
  showArrow?: boolean;
  /**
   * The tooltips classNames.
   */
  classNames?: SlotsToClasses<PopoverSlots>;
}

function Tooltip(props: TooltipProps) {
  const {
    children,
    showArrow = false,
    offset = 8,
    placement = 'top',
    color,
    size,
    radius,
    shadow,
    classNames,
    className,
    ...otherProps
  } = props;

  const slots = useMemo(
    () => popover({ color, size, radius, shadow }),
    [color, size, radius, shadow],
  );

  const baseStyles = clsx(classNames?.base, className);

  const arrowContent = useMemo(() => {
    if (!showArrow) return null;

    return (
      <OverlayArrow className={slots.arrow({ class: classNames?.arrow })}>
        <svg width={12} height={12} viewBox="0 0 12 12">
          <path d="M0 0 L6 6 L12 0" />
        </svg>
      </OverlayArrow>
    );
  }, [classNames?.arrow, showArrow, slots]);

  return (
    <AriaTooltip
      offset={offset}
      placement={placement}
      {...otherProps}
      className={slots.base({ class: baseStyles })}
    >
      {arrowContent}
      {children}
    </AriaTooltip>
  );
}

function TooltipTrigger(props: TooltipTriggerComponentProps) {
  return <AriaTooltipTrigger delay={200} closeDelay={400} {...props} />;
}

export { Tooltip, TooltipTrigger };
