<template>
  <el-dropdown
    ref="dropdownRef"
    :virtual-ref="virtualRef"
    :show-arrow="false"
    :popper-options="{
      modifiers: [{ name: 'offset', options: { offset: [0, 0] } }]
    }"
    virtual-triggering
    trigger="contextmenu"
    placement="bottom-start"
    size="small"
    popper-class="w-180px"
  >
    <template #dropdown>
      <el-dropdown-menu>
        <el-dropdown-item
          v-for="item in currentMenus"
          :key="item.value"
          :icon="item.icon"
          :divided="item.divider"
          @click="item.onclick"
        >
          <div class="flex-1 flex items-center justify-between">
            <span>{{ item.label }}</span>
            <span class="text-10px text-text-secondary">{{ item.fastKey }}</span>
          </div>
        </el-dropdown-item>
      </el-dropdown-menu>
    </template>
  </el-dropdown>
</template>

<script setup lang="ts">
import type { DropdownInstance } from 'element-plus'

import { computed, onBeforeUnmount, ref } from 'vue'
import { useEventBus } from '@vueuse/core'
import {
  LuArrowDown,
  LuArrowDownToLine,
  LuArrowUp,
  LuArrowUpToLine,
  LuClipboard,
  LuCopy,
  LuCopyPlus,
  LuEyeOff,
  LuLock,
  LuScissors,
  LuStar,
  LuTrash2,
  LuUnlock,
  LuZap,
  LuUnlink
} from 'vue-icons-plus/lu'

import { useActionStore } from '@/store/modules/action'
import { useProjectStore } from '@/store/modules/project'

type MenuItem = {
  label: string
  value: string
  fastKey: string
  icon: any
  divider?: boolean
  onclick: () => void
}

const props = defineProps<{
  id: string
  virtualRef: any
  widgetType: 'page' | 'widget'
}>()

const dropdownRef = ref<DropdownInstance>()
const actionStore = useActionStore()
const projectStore = useProjectStore()
const bus = useEventBus('context-menu')
const createCustomCompBus = useEventBus('create-custom-comp')

const unsubscribe = bus.on((_event, id: string) => {
  if (id !== props.id) {
    dropdownRef.value?.handleClose()
  }
})

onBeforeUnmount(() => {
  unsubscribe()
})

const createCustomComponent = () => {
  createCustomCompBus.emit('create', props.id)
}

const isCurrentWidgetLocked = computed(() => {
  return props.widgetType === 'widget' && !!projectStore.activeWidgetMap[props.id]?.locked
})

const widgetMenus = computed<MenuItem[]>(() => {
  const menus: MenuItem[] = [
    {
      label: '复制',
      value: 'copy',
      fastKey: 'Ctrl+C',
      icon: LuCopy,
      onclick: () => actionStore.onCopy()
    },
    {
      label: '复用',
      value: 'duplicate',
      fastKey: 'Ctrl+D',
      icon: LuCopyPlus,
      onclick: () => actionStore.onCopyFrom()
    },
    {
      label: '剪切',
      value: 'cut',
      fastKey: 'Ctrl+X',
      icon: LuScissors,
      onclick: () => actionStore.onCut()
    },
    {
      label: '粘贴',
      value: 'paste',
      fastKey: 'Ctrl+V',
      icon: LuClipboard,
      onclick: () => actionStore.onPaste()
    },
    {
      label: '删除',
      value: 'delete',
      fastKey: 'Delete/Backspace',
      icon: LuTrash2,
      divider: true,
      onclick: () => actionStore.onDelete()
    }
  ]

  if (isCurrentWidgetLocked.value) {
    return menus.filter((item) => ['copy'].includes(item.value))
  }

  if (actionStore.isWidgetBoundById(props.id)) {
    menus.push({
      label: '解绑',
      value: 'unbind',
      fastKey: '',
      icon: LuUnlink,
      onclick: () => actionStore.onUnbind([props.id])
    })
  }

  menus.push(
    {
      label: '隐藏',
      value: 'hidden',
      fastKey: 'Ctrl+H',
      icon: LuEyeOff,
      onclick: () => actionStore.onHidden(true)
    },
    {
      label: '锁定',
      value: 'locked',
      fastKey: 'Ctrl+L',
      icon: LuLock,
      onclick: () => actionStore.onLock(true)
    },
    {
      label: '解锁',
      value: 'unlock',
      fastKey: 'Ctrl+Shift+L',
      icon: LuUnlock,
      onclick: () => actionStore.onLock(false)
    },
    {
      label: '上移一层',
      value: 'up',
      fastKey: 'Ctrl+Up',
      icon: LuArrowUp,
      divider: true,
      onclick: () => actionStore.onLevel('up')
    },
    {
      label: '下移一层',
      value: 'down',
      fastKey: 'Ctrl+Down',
      icon: LuArrowDown,
      onclick: () => actionStore.onLevel('down')
    },
    {
      label: '置顶',
      value: 'top',
      fastKey: 'Ctrl+Shift+Up',
      icon: LuArrowUpToLine,
      onclick: () => actionStore.onLevel('top')
    },
    {
      label: '置底',
      value: 'bottom',
      fastKey: 'Ctrl+Shift+Down',
      icon: LuArrowDownToLine,
      onclick: () => actionStore.onLevel('bottom')
    },
    {
      label: '添加事件',
      value: 'event',
      fastKey: '',
      icon: LuZap,
      divider: true,
      onclick: () => actionStore.onShowEvent()
    },
    {
      label: '创建自定义组件',
      value: 'custom-component',
      fastKey: '',
      icon: LuStar,
      divider: true,
      onclick: createCustomComponent
    }
  )

  return menus
})

const pageMenus: MenuItem[] = [
  {
    label: '粘贴',
    value: 'paste',
    fastKey: 'Ctrl+V',
    icon: LuClipboard,
    onclick: () => actionStore.onPaste()
  },
  {
    label: '隐藏',
    value: 'hidden',
    fastKey: 'Ctrl+H',
    icon: LuEyeOff,
    onclick: () => actionStore.onHidden(true)
  },
  {
    label: '锁定',
    value: 'locked',
    fastKey: 'Ctrl+L',
    icon: LuLock,
    onclick: () => actionStore.onLock(true)
  },
  {
    label: '解锁',
    value: 'unlock',
    fastKey: 'Ctrl+Shift+L',
    icon: LuUnlock,
    onclick: () => actionStore.onLock(false)
  },
  {
    label: '添加事件',
    value: 'event',
    fastKey: '',
    icon: LuZap,
    divider: true,
    onclick: () => actionStore.onShowEvent()
  }
]

const currentMenus = computed(() => {
  return props.widgetType === 'page' ? pageMenus : widgetMenus.value
})

defineExpose({
  handleClose: () => {
    dropdownRef.value?.handleClose()
  },
  handleOpen: () => {
    bus.emit('open', props.id)
    dropdownRef.value?.handleOpen()
  }
})
</script>

<style scoped></style>
