import React, { useEffect, useMemo, useRef } from 'react'
import { useInventoryContext } from '../../context/InventoryContext'
import { useScale } from '../../context/ScaleContext'
import { ItemCanvas } from '../ItemCanvas'
import { useMobile } from '../../hooks/useMobile'
import { globalMouse } from '../../utils/globalMouse'

/**
 * CursorItem — optimized to bypass React re-renders on mouse move.
 * Uses direct DOM manipulation via refs to update position every frame.
 * Only re-renders when heldItem or contentSize changes (for ItemCanvas updates).
 */
export function CursorItem() {
  const { heldItem, isDragging, dragSlots, dragRemainder } = useInventoryContext()
  const { contentSize } = useScale()
  const isMobile = useMobile()
  const containerRef = useRef<HTMLDivElement>(null)
  const rafRef = useRef(0)
  const halfSizeRef = useRef(Math.round(contentSize / 2))

  // Determine display item: during spread, show remainder count
  const displayItem = useMemo(() => {
    if (isDragging && dragSlots.length > 1 && heldItem && dragRemainder !== null) {
      return { ...heldItem, count: dragRemainder }
    }
    return heldItem
  }, [isDragging, dragSlots.length, heldItem, dragRemainder])

  // Update halfSize when contentSize changes
  useEffect(() => {
    halfSizeRef.current = Math.round(contentSize / 2)
  }, [contentSize])

  // Direct DOM position updates — no React state, no re-renders
  useEffect(() => {
    if (isMobile || !heldItem || !containerRef.current) {
      // Cancel RAF if item dropped or mobile
      if (rafRef.current) {
        cancelAnimationFrame(rafRef.current)
        rafRef.current = 0
      }
      return
    }

    const container = containerRef.current

    // Immediately position at current cursor
    const half = halfSizeRef.current
    container.style.left = `${globalMouse.x - half}px`
    container.style.top = `${globalMouse.y - half}px`

    // RAF loop — direct DOM updates, no React state
    const update = () => {
      if (!containerRef.current) return
      const half = halfSizeRef.current
      container.style.left = `${globalMouse.x - half}px`
      container.style.top = `${globalMouse.y - half}px`
      rafRef.current = requestAnimationFrame(update)
    }
    rafRef.current = requestAnimationFrame(update)

    return () => {
      if (rafRef.current) {
        cancelAnimationFrame(rafRef.current)
        rafRef.current = 0
      }
    }
  }, [isMobile, heldItem])

  // Only re-render when heldItem or contentSize changes (for ItemCanvas)
  if (!heldItem || isMobile) return null

  return (
    <div
      ref={containerRef}
      className="mc-inv-cursor-item"
      style={{
        position: 'fixed',
        width: contentSize,
        height: contentSize,
        pointerEvents: 'none',
        zIndex: 9999,
        // left/top set directly by RAF, not via React style prop
      }}
    >
      <ItemCanvas
        item={displayItem!}
        size={contentSize}
        style={{ position: 'absolute', top: 0, left: 0 }}
      />
      {isDragging && dragSlots.length > 1 && dragRemainder === 0 && (
        <span
          className="mc-inv-cursor-zero"
          style={{
            position: 'absolute',
            bottom: 0,
            right: 0,
            fontSize: Math.max(7, Math.round(contentSize * 0.5)),
            fontFamily: "'Minecraftia', 'Minecraft', monospace",
            color: '#ffff00',
            textShadow: '1px 1px 0 #3f3f00',
            lineHeight: 1,
            pointerEvents: 'none',
            zIndex: 1,
          }}
        >
          0
        </span>
      )}
    </div>
  )
}
