import {
  useState,
  useRef,
  cloneElement,
  isValidElement,
  type ReactElement,
  type ReactNode,
} from 'react'
import {
  useFloating,
  useHover,
  useFocus,
  useDismiss,
  useRole,
  useInteractions,
  offset,
  flip,
  shift,
  arrow,
  FloatingArrow,
  FloatingPortal,
  autoUpdate,
  type Placement,
} from '@floating-ui/react'
import { cn } from '@/lib/utils'

export interface TooltipProps {
  content: ReactNode
  placement?: Placement
  delay?: number | { open?: number; close?: number }
  children: ReactElement
  className?: string
}

export function Tooltip({
  content,
  placement = 'top',
  delay = { open: 400, close: 0 },
  children,
  className,
}: TooltipProps) {
  const [open, setOpen] = useState(false)
  const arrowRef = useRef(null)

  const { refs, floatingStyles, context } = useFloating({
    open,
    onOpenChange: setOpen,
    placement,
    whileElementsMounted: autoUpdate,
    middleware: [
      offset(8),
      flip({ fallbackAxisSideDirection: 'start' }),
      shift({ padding: 8 }),
      arrow({ element: arrowRef }),
    ],
  })

  const hover = useHover(context, { delay })
  const focus = useFocus(context)
  const dismiss = useDismiss(context)
  const role = useRole(context, { role: 'tooltip' })

  const { getReferenceProps, getFloatingProps } = useInteractions([
    hover,
    focus,
    dismiss,
    role,
  ])

  if (!isValidElement(children)) return children

  return (
    <>
      {cloneElement(children, {
        ref: refs.setReference,
        ...getReferenceProps(),
      } as Record<string, unknown>)}
      {open && (
        <FloatingPortal>
          <div
            ref={refs.setFloating}
            style={floatingStyles}
            className={cn(
              'z-50 max-w-xs rounded-default bg-surface px-3 py-1.5 font-sans text-small text-text shadow-md',
              className,
            )}
            {...getFloatingProps()}
          >
            {content}
            <FloatingArrow
              ref={arrowRef}
              context={context}
              className="fill-surface drop-shadow-sm"
              width={12}
              height={6}
            />
          </div>
        </FloatingPortal>
      )}
    </>
  )
}
