import React, { useRef, useEffect } from 'react'
import { createPortal } from 'react-dom'
import type { ItemStack } from '../../types'
import { useScale } from '../../context/ScaleContext'
import { globalMouse } from '../../utils/globalMouse'
import { ItemTooltipBody } from './ItemTooltipBody'
import styles from './Tooltip.module.css'

interface TooltipProps {
  item: ItemStack
  visible: boolean
}

export function Tooltip({ item, visible }: TooltipProps) {
  const { scale } = useScale()
  const ref = useRef<HTMLDivElement>(null)

  // Position the tooltip directly via DOM, bypassing React state updates.
  // Called on every mousemove and whenever visible/item/scale changes.
  const applyPosition = () => {
    const el = ref.current
    if (!el) return
    const tw = el.offsetWidth
    const th = el.offsetHeight
    const vw = window.innerWidth
    const vh = window.innerHeight
    const gapX = 12
    const gapY = 2

    let x = globalMouse.x + gapX
    let y = globalMouse.y - th - gapY  // above cursor by default

    if (x + tw > vw - 4) x = globalMouse.x - tw - gapX
    if (y < 4) y = globalMouse.y + gapY  // flip below if no space above
    if (y + th > vh - 4) y = vh - th - 4

    el.style.left = `${x}px`
    el.style.top = `${y}px`
    el.style.visibility = 'visible'
  }

  useEffect(() => {
    if (!visible) return

    // Initial position immediately after mounting / becoming visible
    applyPosition()

    const onMove = () => applyPosition()
    window.addEventListener('mousemove', onMove, { passive: true })
    return () => window.removeEventListener('mousemove', onMove)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [visible, item, scale])

  if (!visible) return null

  const fs = Math.round(8 * scale)
  const pad = Math.round(3 * scale)
  const gap2 = Math.round(0.5 * scale)

  const tooltip = (
    <div
      ref={ref}
      className={['mc-inv-tooltip', styles.tooltip].join(' ')}
      style={{
        position: 'fixed',
        left: -9999,
        top: -9999,
        zIndex: 10000,
        fontSize: fs,
        padding: pad,
        gap: gap2,
        width: 'max-content',
        // Start invisible; applyPosition sets visibility after measuring dimensions
        visibility: 'hidden',
        pointerEvents: 'none',
      }}
    >
      <ItemTooltipBody item={item} />
    </div>
  )

  // Portal to document.body so position:fixed works even inside transformed ancestors
  return createPortal(tooltip, document.body)
}
