<template>
  <context-menu ref="menu" :model="items" :pt="passThroughConfig">
    <template #item="{ item, props }">
      <cp-menu-item
        v-bind="{ ...item, ...props.action }"
        :leading-icon="item.icon"
        @async-complete="hide"
        @click="hide"
      />
    </template>
  </context-menu>
</template>

<script setup lang="ts">
import ContextMenu from 'primevue/contextmenu'
import type { MenuItem } from 'primevue/menuitem'
import { ref } from 'vue'

import CpMenuItem from '@/components/CpMenuItem.vue'

export interface Props {
  items: MenuItem[]
}

defineProps<Props>()

const menu = ref<InstanceType<typeof ContextMenu>>()

const passThroughConfig = {
  root: { class: 'cpContextualMenu' },
  item: { class: 'cpContextualMenu__item' },
  transition: { name: 'scale-elastic', duration: 100 },
}

const show = (event: MouseEvent) => {
  const { x, y } = event

  if (x !== 0 && y !== 0) {
    return menu.value?.show(event)
  }

  // Keyboard activation → anchor to the trigger element
  const rect = (event.currentTarget as HTMLElement).getBoundingClientRect()

  const fakeEvent = new MouseEvent('click', {
    ...event,
    clientX: rect.left + rect.width,
    clientY: rect.bottom,
  })

  menu.value?.show(fakeEvent)
}

const hide = () => menu.value?.hide()

defineExpose({ show, hide })
</script>

<style lang="scss">
.cpContextualMenu {
  min-width: calc(var(--cp-dimensions-1) * 62.5);
  padding: var(--cp-spacing-sm) 0;
  border-radius: var(--cp-radius-md);
  background-color: var(--cp-background-primary);
  box-shadow: var(--cp-shadows-overlay);
  font-size: var(--cp-text-size-sm);
}
</style>
