<template>
  <slot name="trigger" @click.prevent="console.log(222)"></slot>
  <!-- 遮罩：点击外部关闭 -->
  <div v-if="visible" class="pm-mask" @click="close" @contextmenu.prevent></div>

  <!-- 菜单容器 -->
  <Transition name="pm-fade">
    <div
      v-if="visible"
      class="pm-wrapper"
      :style="{ top: y + 'px', left: x + 'px' }"
      @contextmenu.prevent
    ></div>
  </Transition>
</template>

<script setup>
import { nextTick, onBeforeUnmount, ref, watch } from 'vue'

const props = defineProps({
  items: { type: Array, default: () => [] }, // 菜单项
  show: Boolean, // 显示开关
  point: { type: Object, default: () => ({ x: 0, y: 0 }) }, // 坐标
})

const emit = defineEmits(['update:show', 'select'])

const visible = ref(false)
const x = ref(0)
const y = ref(0)

watch(
  () => props.show,
  async (val) => {
    if (!val) return (visible.value = false)
    // 先拿到坐标再渲染，防止超出屏幕
    x.value = props.point.x
    y.value = props.point.y
    visible.value = true
    await nextTick()
    fixPosition()
    // 全局监听
    document.addEventListener('keydown', onKeyDown)
  },
)

function fixPosition() {
  const el = document.querySelector('.pm-wrapper')
  if (!el) return
  const { innerWidth, innerHeight } = window
  const { offsetWidth: w, offsetHeight: h } = el
  if (x.value + w > innerWidth) x.value = innerWidth - w - 4
  if (y.value + h > innerHeight) y.value = innerHeight - h - 4
}

function close() {
  visible.value = false
  emit('update:show', false)
  document.removeEventListener('keydown', onKeyDown)
}

function onKeyDown(e) {
  if (e.key === 'Escape') close()
}

function onClick(item) {
  if (item.disabled) return
  emit('select', item)
  close()
}

onBeforeUnmount(() => document.removeEventListener('keydown', onKeyDown))
</script>

<style scoped>
.pm-mask {
  position: fixed;
  inset: 0;
  z-index: 998;
}
.pm-wrapper {
  position: fixed;
  z-index: 999;
  background: #fff;
  border-radius: 6px;
  padding: 4px 0;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
  user-select: none;
}
.pm-fade-enter-active,
.pm-fade-leave-active {
  transition:
    opacity 0.15s,
    transform 0.15s;
  transform-origin: left top;
}
.pm-fade-enter-from,
.pm-fade-leave-to {
  opacity: 0;
  transform: scale(0.95);
}
</style>
