import Tippy from '@tippyjs/react'
import type { JSXElementConstructor, ReactElement } from 'react'

import Box from '../box'
import { useUp, v } from '../core'
import { Link } from '../link'
import { bg, pointerPlacement, pointerSize } from './consts'
import type { TooltipProps } from './tooltip.types'
import { TooltipContent } from './tooltipContent'

const stripHtmlTags = (html: string): string => {
  const withoutTags = html.replace(/<[^>]*>/g, '')
  // Decode HTML entities
  const textarea = document.createElement('textarea')
  textarea.innerHTML = withoutTags
  return textarea.value
}

/**
 * A simple text popup hint.
 *
 * Displayed on mouse enter, and is hidden on mouse leave.
 *
 * */
export const Tooltip = (props: TooltipProps) => {
  const {
    children,
    fontSize = '16px',
    linkText,
    linkProps,
    minWidth = '200px',
    maxWidth = '400px',
    text = 'Tooltip',
    placement = 'top',
    disabled = false,
    visible = false,
    offset = [0, 2],
    whiteSpace = 'pre-wrap',
    wordBreak = 'break-word',
  } = props

  const isDesktop = useUp('md')

  return (
    <Tippy
      content={
        !!text && (
          <TooltipContent
            disabled={disabled}
            fontSize={fontSize}
            maxWidth={maxWidth}
            minWidth={minWidth}
            whiteSpace={whiteSpace}
            wordBreak={wordBreak}
          >
            {isDesktop && (
              <Box
                bg={disabled ? bg.disabled : bg.regular}
                bottom={pointerPlacement[placement].bottom}
                h={`${pointerSize}px`}
                left={pointerPlacement[placement].left}
                position="absolute"
                right={pointerPlacement[placement].right}
                top={pointerPlacement[placement].top}
                transform={`translate(${pointerPlacement[placement].translate}) rotate(45deg)`}
                w={`${pointerSize}px`}
              />
            )}
            <v.div>
              {stripHtmlTags(text)}
              {!!linkText && (
                <>
                  &nbsp;
                  <Link variant="white" {...linkProps}>
                    {linkText}
                  </Link>
                </>
              )}
            </v.div>
          </TooltipContent>
        )
      }
      interactive
      offset={offset}
      placement={placement}
      popperOptions={{
        modifiers: [
          {
            name: 'flip',
            enabled: false,
          },
        ],
      }}
      visible={visible || undefined}
    >
      {children as ReactElement<any, string | JSXElementConstructor<any>> | undefined}
    </Tippy>
  )
}

Tooltip.displayName = 'Tooltip'

export default Tooltip
