"use client"
import { type PointerEvent } from "react"
import { useReactFlow } from "@xyflow/react"

interface Bounds {
  minWidth?: number
  maxWidth?: number
  minHeight?: number
  maxHeight?: number
}

/** 拖动期间持续更新 ReactFlow node 的 width/height，同时写到 style.width/height 让 wrapper 真实渲染。
 *  自适应 viewport zoom。不走 xyflow NodeResizeControl（glass-node overflow:hidden + reserved-type CSS 干扰下不响应）。 */
function startResize(
  e: PointerEvent<HTMLDivElement>,
  setNodes: ReturnType<typeof useReactFlow>["setNodes"],
  getZoom: ReturnType<typeof useReactFlow>["getZoom"],
  axis: "x" | "y" | "xy",
  bounds: Required<Bounds>,
) {
  e.preventDefault()
  e.stopPropagation()
  const target = e.currentTarget
  const nodeEl = target.closest(".react-flow__node") as HTMLElement | null
  const nodeId = nodeEl?.getAttribute("data-id")
  if (!nodeId || !nodeEl) return
  target.setPointerCapture(e.pointerId)

  const startX = e.clientX
  const startY = e.clientY
  const zoom = getZoom() || 1
  // computedStyle width/height are already in ReactFlow node coordinates.
  // Only pointer movement needs zoom normalization because clientX/Y are viewport pixels.
  const startWidth = parseFloat(getComputedStyle(nodeEl).width)
  const startHeight = parseFloat(getComputedStyle(nodeEl).height)

  const onMove = (ev: globalThis.PointerEvent) => {
    const rawDx = ev.clientX - startX
    const rawDy = ev.clientY - startY
    if (Math.abs(rawDx) < 2 && Math.abs(rawDy) < 2) return
    const dx = rawDx / zoom
    const dy = rawDy / zoom
    const wantW = axis === "y" ? null : Math.max(bounds.minWidth, Math.min(bounds.maxWidth, startWidth + dx))
    const wantH = axis === "x" ? null : Math.max(bounds.minHeight, Math.min(bounds.maxHeight, startHeight + dy))
    setNodes((nodes) =>
      nodes.map((n) => {
        if (n.id !== nodeId) return n
        const nextStyle = { ...n.style }
        const patch: Record<string, unknown> = {}
        if (wantW !== null) { patch.width = wantW; nextStyle.width = wantW }
        if (wantH !== null) { patch.height = wantH; nextStyle.height = wantH }
        return { ...n, ...patch, style: nextStyle }
      }),
    )
  }
  const onUp = () => {
    window.removeEventListener("pointermove", onMove)
    window.removeEventListener("pointerup", onUp)
    try { target.releasePointerCapture(e.pointerId) } catch {}
  }
  window.addEventListener("pointermove", onMove)
  window.addEventListener("pointerup", onUp)
}

/** 右边缘把手 — 只改宽度 */
export function ResizeRight({ minWidth = 240, maxWidth = 1400 }: Bounds) {
  const { setNodes, getZoom } = useReactFlow()
  return (
    <div
      onPointerDown={(e) => startResize(e, setNodes, getZoom, "x", { minWidth, maxWidth, minHeight: 0, maxHeight: 0 })}
      title="拖动调整宽度"
      className="nodrag absolute z-20 hover:bg-violet-400/60 active:bg-violet-400/80 transition rounded-r"
      style={{ right: 0, top: 12, bottom: 12, width: 6, cursor: "ew-resize", touchAction: "none" }}
    />
  )
}

/** 右下角把手 — 同时改宽和高 */
export function ResizeBR({
  minWidth = 240, maxWidth = 1400, minHeight = 120, maxHeight = 1400,
}: Bounds) {
  const { setNodes, getZoom } = useReactFlow()
  return (
    <div
      onPointerDown={(e) => startResize(e, setNodes, getZoom, "xy", { minWidth, maxWidth, minHeight, maxHeight })}
      title="拖动调整大小（宽 × 高）"
      className="nodrag absolute z-30 hover:bg-violet-400/80 active:bg-violet-400 transition"
      style={{
        right: 0,
        bottom: 0,
        width: 14,
        height: 14,
        cursor: "nwse-resize",
        touchAction: "none",
        background: "linear-gradient(135deg, transparent 50%, rgba(167,139,250,0.55) 50%)",
      }}
    />
  )
}
