import { type PropsWithChildren, useState } from 'react'

import { tooltipVariants } from './variants'

import styles from './tooltip.module.css'
import { Typography } from '../Typography'

type TooltipPosition = 'left' | 'right' | 'top' | 'bottom'
type VerticalArrow = 'top' | 'bottom' | 'center'
type HorizontalArrow = 'left' | 'right' | 'center'

type ValidArrowMap = {
  left: VerticalArrow
  right: VerticalArrow
  top: HorizontalArrow
  bottom: HorizontalArrow
}

type ValidArrow<P extends TooltipPosition> = P extends keyof ValidArrowMap
  ? ValidArrowMap[P]
  : never

interface TooltipProps<P extends TooltipPosition = TooltipPosition> {
  heading?: string
  text?: string
  position: P
  arrow: ValidArrow<P>
  isTouchable?: boolean
  isVisible?: boolean
}

export function Tooltip<P extends TooltipPosition>({
  heading,
  text,
  position,
  arrow,
  children,
  isTouchable = false,
  isVisible = true,
}: PropsWithChildren<TooltipProps<P>>) {
  const className = tooltipVariants({ position, arrow })
  const [isActive, setIsActive] = useState(false)

  function handleToggle() {
    setIsActive((prevState) => !prevState)
    setTimeout(() => {
      setIsActive(false)
    }, 3000)
  }

  function handleKeyDown(event: React.KeyboardEvent<HTMLDivElement>) {
    if (event.key === 'Enter' || event.key === ' ') {
      event.preventDefault()
      handleToggle()
    }
  }

  if (!isVisible) {
    return <> {children} </>
  }

  return (
    <div
      className={styles.tooltipContainer}
      role="tooltip"
      aria-label={text}
      tabIndex={0}
      onClick={isTouchable ? undefined : handleToggle}
      onTouchStart={isTouchable ? handleToggle : undefined}
      onKeyDown={handleKeyDown}
      data-active={isActive}
    >
      <div className={className}>
        {heading ? (
          <Typography variant="Body/Supporting text (caption)/smBold">
            <p>{heading}</p>
          </Typography>
        ) : null}
        {text ? (
          <Typography variant="Body/Supporting text (caption)/smRegular">
            <p>{text} </p>
          </Typography>
        ) : null}
      </div>
      {children}
    </div>
  )
}
