import { nextTick, ref } from 'vue'
import { useClickOutside } from './useClickOutside'

// Teleport(body) + fixed 위치로 띄우는 드롭다운 메뉴 공용 훅.
// 트리거 기준 좌표 계산 · open 토글 · 바깥클릭/ESC/스크롤 닫기를 한 곳으로 모은다.
// (DropdownSelect, StatusSelect 등 스크롤/overflow 컨테이너 안에서도 안 잘리는 메뉴에 사용)
//
// - align:      트리거 좌/우 끝 기준 정렬 (기본 'left')
// - matchWidth: 메뉴 최소 너비를 트리거 너비에 맞출지 (기본 false)
// - gap:        트리거 하단과 메뉴 사이 간격(px) (기본 6)
// - esc:        ESC 로 닫을지 (기본 true)
export function useDropdownMenu(
  opts: {
    align?: 'left' | 'right'
    matchWidth?: boolean
    gap?: number
    esc?: boolean
  } = {},
) {
  const { align = 'left', matchWidth = false, gap = 6, esc = true } = opts

  const open = ref(false)
  const triggerRef = ref<HTMLElement | null>(null)
  const menuRef = ref<HTMLElement | null>(null)
  // 메뉴 fixed 위치(트리거 기준 계산)
  const menuStyle = ref<Record<string, string>>({})

  function position(): void {
    const el = triggerRef.value
    if (!el) return
    const r = el.getBoundingClientRect()
    const style: Record<string, string> = { top: `${r.bottom + gap}px` }
    if (matchWidth) style.minWidth = `${r.width}px`
    if (align === 'right') {
      style.right = `${Math.max(0, window.innerWidth - r.right)}px`
    } else {
      style.left = `${r.left}px`
    }
    menuStyle.value = style
  }

  function toggle(): void {
    open.value = !open.value
    if (open.value) void nextTick(position)
  }
  function close(): void {
    open.value = false
  }

  // 바깥클릭(트리거/메뉴 외부)·ESC·스크롤(위치 어긋남) 닫기
  useClickOutside(open, close, [triggerRef, menuRef], {
    event: 'click',
    esc,
    closeOnScroll: true,
  })

  return { open, triggerRef, menuRef, menuStyle, toggle, close, position }
}
