<script setup lang="ts">
import { ref } from "vue";

export interface ContextMenuItem {
  label?: string;
  icon?: string;
  action?: () => void;
  separator?: boolean;
  disabled?: boolean;
  danger?: boolean;
}

const visible = ref(false);
const posX = ref(0);
const posY = ref(0);
const menuItems = ref<ContextMenuItem[]>([]);

function open(event: MouseEvent, items: ContextMenuItem[]) {
  posX.value = event.clientX;
  posY.value = event.clientY;
  menuItems.value = items;
  visible.value = true;
}

function close() {
  visible.value = false;
}

function handleClick(item: ContextMenuItem) {
  if (item.disabled || !item.action) return;
  item.action();
  close();
}

defineExpose({ open });
</script>

<template>
  <Teleport to="body">
    <div v-if="visible" class="fixed inset-0 z-50" @click="close" @contextmenu.prevent="close">
      <div
        class="absolute bg-zinc-800 border border-zinc-700 rounded-lg shadow-xl py-1 min-w-[160px] z-50"
        :style="{ left: `${posX}px`, top: `${posY}px` }"
      >
        <template v-for="(item, i) in menuItems" :key="i">
          <div v-if="item.separator" class="border-t border-zinc-700 my-1" />
          <button
            v-else
            class="w-full text-left px-3 py-1.5 text-sm hover:bg-zinc-700 disabled:opacity-40 disabled:cursor-not-allowed flex items-center gap-2"
            :class="item.danger ? 'text-red-400 hover:text-red-300' : 'text-zinc-200'"
            :disabled="item.disabled"
            @click="handleClick(item)"
          >
            <span v-if="item.icon" class="w-4 h-4 flex-shrink-0" v-html="item.icon" />
            {{ item.label }}
          </button>
        </template>
      </div>
    </div>
  </Teleport>
</template>
