import { useMemo } from 'react'
import { useDominoStore } from './domino-hooks'
import { useTransform } from './use-transform'
import { getDominoDOM } from './dom-utils'
import { getElementWorldRect } from './math'

export interface AnchorRect {
  left: number
  top: number
  width: number
  height: number
  right: number
  bottom: number
  centerX: number
  centerY: number
}

/**
 * Hook to get the screen-space coordinates of a Domino element.
 * Useful for anchoring external UI components (like Modals or Tooltips) to canvas elements.
 */
export function useDominoAnchor(
  elementId: string | null,
  containerRef: React.RefObject<HTMLElement | null>,
  screenSpace = false,
): AnchorRect | null {
  const elements = useDominoStore(state => state.elements)
  const placeholders = useDominoStore(state => state.placeholders)
  const element = useDominoStore(state =>
    elementId
      ? state.elements[elementId] || state.placeholders[elementId]
      : null,
  )
  const viewport = useDominoStore(state => state.viewport)
  const { worldToScreen } = useTransform()

  return useMemo((): AnchorRect | null => {
    if (!element || !containerRef.current) return null

    // 1. [Better Calc] If screenSpace is enabled, try to use direct DOM measurement for precision
    // This automatically handles native CSS transforms, scaling, and complex nesting.
    if (screenSpace) {
      const domEl = getDominoDOM(element.id)
      if (domEl) {
        const rect = domEl.getBoundingClientRect()
        return {
          left: rect.left,
          top: rect.top,
          width: rect.width,
          height: rect.height,
          right: rect.right,
          bottom: rect.bottom,
          centerX: rect.left + rect.width / 2,
          centerY: rect.top + rect.height / 2,
        }
      }
    }

    // 2. [Original Fallback] Manual math calculation (for non-screenSpace or when DOM is not yet ready)
    // Calculate absolute world position using utility
    const worldRect = getElementWorldRect(element, elements)
    const worldX = worldRect.x
    const worldY = worldRect.y

    // Calculate the 4 corners in world space
    const rad = ((element.rotation || 0) * Math.PI) / 180

    // 当 width/height 为 0 时（表示 auto），从 DOM 获取实际渲染尺寸
    let elWidth = element.width
    let elHeight = element.height
    if (!elWidth || !elHeight) {
      const domEl = getDominoDOM(element.id)
      if (domEl) {
        // Use offsetWidth/Height as they reflect layout size before CSS transforms (like rotation)
        const scale = viewport.scale || 1
        if (!elWidth) elWidth = domEl.offsetWidth / scale
        if (!elHeight) elHeight = domEl.offsetHeight / scale
      }
    }

    const cx = worldX + elWidth / 2
    const cy = worldY + elHeight / 2

    const corners = [
      { x: worldX, y: worldY }, // tl
      { x: worldX + elWidth, y: worldY }, // tr
      { x: worldX + elWidth, y: worldY + elHeight }, // br
      { x: worldX, y: worldY + elHeight }, // bl
    ]

    const rotatedCorners = corners.map(p => {
      // Rotate around center
      const dx = p.x - cx
      const dy = p.y - cy
      const rx = dx * Math.cos(rad) - dy * Math.sin(rad)
      const ry = dx * Math.sin(rad) + dy * Math.cos(rad)
      return { x: rx + cx, y: ry + cy }
    })

    // Convert all corners to screen space
    // If NOT screenSpace, worldToScreen returns relative to the canvas.
    // If screenSpace, we want viewport-relative coordinates for fixed positioning.
    const screenCorners = rotatedCorners.map(p => worldToScreen(p.x, p.y))

    // Find the bounding box of the screen corners
    const minX = Math.min(...screenCorners.map(p => p.x))
    const minY = Math.min(...screenCorners.map(p => p.y))
    const maxX = Math.max(...screenCorners.map(p => p.x))
    const maxY = Math.max(...screenCorners.map(p => p.y))

    return {
      left: minX,
      top: minY,
      width: maxX - minX,
      height: maxY - minY,
      right: maxX,
      bottom: maxY,
      centerX: (minX + maxX) / 2,
      centerY: (minY + maxY) / 2,
    }
  }, [
    element,
    elements,
    placeholders,
    viewport,
    containerRef,
    worldToScreen,
    screenSpace,
  ])
}
