import * as React from 'react'
import { motion } from 'framer-motion'
import * as TooltipPrimitive from '@radix-ui/react-tooltip'
import { cn } from '@/lib/utils'
import { MOTION_SCALE_IN } from '@/lib/motion'
import { getThemeFromDocument } from './theme-from-document'

const TooltipProvider = TooltipPrimitive.Provider

const TooltipRoot = TooltipPrimitive.Root

const TooltipTrigger = TooltipPrimitive.Trigger

const TooltipContent = React.forwardRef<
  React.ElementRef<typeof TooltipPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> & {
    /** When provided (e.g. from ThemeStyleProvider), used for portal wrapper instead of getThemeFromDocument */
    dataStyle?: string
    dataTheme?: string
  }
>(({ className, sideOffset = 8, children, dataStyle, dataTheme, ...props }, ref) => {
  const fromDoc = getThemeFromDocument()
  const dataProps =
    dataStyle !== undefined
      ? { 'data-style': dataStyle, 'data-theme': dataTheme ?? fromDoc['data-theme'] ?? '' }
      : fromDoc
  return (
    <TooltipPrimitive.Portal>
      <div style={{ display: 'contents' }} {...dataProps}>
        <TooltipPrimitive.Content
          ref={ref}
          sideOffset={sideOffset}
          className={cn(
            'z-50 max-w-60 overflow-hidden rounded px-2 py-1 text-xs leading-5',
            'bg-bg-highlight text-text-on-primary shadow-sm',
            className
          )}
          {...props}
        >
          <motion.div {...MOTION_SCALE_IN}>
            {children}
          </motion.div>
        </TooltipPrimitive.Content>
      </div>
    </TooltipPrimitive.Portal>
  )
})
TooltipContent.displayName = TooltipPrimitive.Content.displayName

export interface TooltipProps {
  content: React.ReactNode
  children: React.ReactNode
  side?: 'top' | 'right' | 'bottom' | 'left'
  contentClassName?: string
  /** When provided, portal content uses this data-style (e.g. from ThemeStyleProvider) */
  dataStyle?: string
  /** When provided, portal content uses this data-theme */
  dataTheme?: string
}

function Tooltip({ content, children, side = 'top', contentClassName, dataStyle, dataTheme }: TooltipProps) {
  return (
    <TooltipProvider delayDuration={300}>
      <TooltipRoot>
        <TooltipTrigger asChild>{children}</TooltipTrigger>
        <TooltipContent side={side} className={contentClassName} dataStyle={dataStyle} dataTheme={dataTheme}>
          {content}
        </TooltipContent>
      </TooltipRoot>
    </TooltipProvider>
  )
}
Tooltip.displayName = 'Tooltip'

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