import * as TooltipPrimitive from '@radix-ui/react-tooltip'
import type * as React from 'react'
import { cn } from '../../utils'
import { popoverContentClassName } from '../Popover/Popover'

/** Provides the delay and open behavior for all Tooltip instances in a subtree. Wrap your layout root once — not needed around every tooltip. */
const TooltipProvider = TooltipPrimitive.Provider

export type TooltipProps = React.ComponentProps<typeof TooltipPrimitive.Root>
/**
 * Root state container for a tooltip. Manages open/closed state and hover delay.
 * Compose with TooltipTrigger and TooltipContent.
 */
const Tooltip = TooltipPrimitive.Root
Tooltip.displayName = 'Tooltip'

export type TooltipTriggerProps = React.ComponentProps<
  typeof TooltipPrimitive.Trigger
>

/** Element that opens the tooltip on hover or focus. Use `asChild` to make any element the trigger. */
const TooltipTrigger = TooltipPrimitive.Trigger

export type TooltipContentProps = React.ComponentPropsWithoutRef<
  typeof TooltipPrimitive.Content
>

type TooltipContentPropsWithRef = TooltipContentProps & {
  ref?: React.Ref<React.ElementRef<typeof TooltipPrimitive.Content>>
}

/**
 * Floating content panel of the tooltip. Renders inside a portal. Accepts
 * `side` and `align` for positioning. Add `<TooltipArrow />` inside for a
 * directional arrow.
 */
const TooltipContent = ({
  className,
  sideOffset = 4,
  ref,
  ...props
}: TooltipContentPropsWithRef) => (
  <TooltipPrimitive.Portal>
    <TooltipPrimitive.Content
      ref={ref}
      sideOffset={sideOffset}
      className={cn(popoverContentClassName, className)}
      {...props}
    />
  </TooltipPrimitive.Portal>
)

type TooltipArrowProps = React.ComponentPropsWithoutRef<
  typeof TooltipPrimitive.Arrow
> & {
  ref?: React.Ref<React.ElementRef<typeof TooltipPrimitive.Arrow>>
}

/** Directional arrow rendered inside TooltipContent. Points toward the trigger. */
const TooltipArrow = ({ className, ref, ...props }: TooltipArrowProps) => (
  <TooltipPrimitive.Arrow
    ref={ref}
    className={cn('fill-popover', className)}
    {...props}
  />
)
TooltipArrow.displayName = TooltipPrimitive.Arrow.displayName
TooltipTrigger.displayName = TooltipPrimitive.Trigger.displayName
TooltipContent.displayName = TooltipPrimitive.Content.displayName

export {
  Tooltip,
  TooltipTrigger,
  TooltipContent,
  TooltipProvider,
  TooltipArrow,
}
