<template>
  <div 
    class="editable-element"
    ref="elementRef"
    :id="`editable-element-${elementInfo.id}`"
    :style="{
      zIndex: elementIndex,
    }"
  >
    <component
      :is="currentElementComponent"
      :elementInfo="elementInfo"
      :selectElement="selectElement"
      :contextmenus="contextmenus"
    ></component>
  </div>
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import { storeToRefs } from 'pinia'
import { ElementTypes, type PPTElement } from '@/types/slides'
import type { ContextmenuItem } from '@/components/Contextmenu/types'

import useLockElement from '@/hooks/useLockElement'
import useDeleteElement from '@/hooks/useDeleteElement'
import useCombineElement from '@/hooks/useCombineElement'
import useOrderElement from '@/hooks/useOrderElement'
import useAlignElementToCanvas from '@/hooks/useAlignElementToCanvas'
import useCopyAndPasteElement from '@/hooks/useCopyAndPasteElement'
import useSelectElement from '@/hooks/useSelectElement'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import { useSlidesStore } from '@/store'
import message from '@/utils/message'
import { lang } from '@/main'

import { ElementOrderCommands, ElementAlignCommands } from '@/types/edit'

import ImageElement from '@/views/components/element/ImageElement/index.vue'
import TextElement from '@/views/components/element/TextElement/index.vue'
import ShapeElement from '@/views/components/element/ShapeElement/index.vue'
import LineElement from '@/views/components/element/LineElement/index.vue'
import ChartElement from '@/views/components/element/ChartElement/index.vue'
import TableElement from '@/views/components/element/TableElement/index.vue'
import LatexElement from '@/views/components/element/LatexElement/index.vue'
import VideoElement from '@/views/components/element/VideoElement/index.vue'
import AudioElement from '@/views/components/element/AudioElement/index.vue'
import FrameElement from '@/views/components/element/FrameElement/index.vue'

const props = defineProps<{
  elementInfo: PPTElement
  elementIndex: number
  isMultiSelect: boolean
  selectElement: (e: MouseEvent | TouchEvent, element: PPTElement, canMove?: boolean) => void
  openLinkDialog: () => void
  openWebpageLinkEditDialog: (elementId: string, currentUrl: string) => void
}>()

const currentElementComponent = computed<unknown>(() => {
  const elementTypeMap = {
    [ElementTypes.IMAGE]: ImageElement,
    [ElementTypes.TEXT]: TextElement,
    [ElementTypes.SHAPE]: ShapeElement,
    [ElementTypes.LINE]: LineElement,
    [ElementTypes.CHART]: ChartElement,
    [ElementTypes.TABLE]: TableElement,
    [ElementTypes.LATEX]: LatexElement,
    [ElementTypes.VIDEO]: VideoElement,
    [ElementTypes.AUDIO]: AudioElement,
    [ElementTypes.FRAME]: FrameElement,
  }
  return elementTypeMap[props.elementInfo.type] || null
})

const { orderElement } = useOrderElement()
const { alignElementToCanvas } = useAlignElementToCanvas()
const { combineElements, uncombineElements } = useCombineElement()
const { deleteElement } = useDeleteElement()
const { lockElement, unlockElement } = useLockElement()
const { copyElement, pasteElement, cutElement } = useCopyAndPasteElement()
const { selectAllElements } = useSelectElement()

const contextmenus = (): ContextmenuItem[] => {
  if (props.elementInfo.lock) {
    return [{
      text: lang.ssUnlock, 
      handler: () => unlockElement(props.elementInfo),
    }]
  }

  const baseMenu = [
    {
      text: lang.ssCut,
      subText: 'Ctrl + X',
      handler: cutElement,
    },
    {
      text: lang.ssCopy,
      subText: 'Ctrl + C',
      handler: copyElement,
    },
    {
      text: lang.ssPaste,
      subText: 'Ctrl + V',
      handler: pasteElement,
    },
    { divider: true },
    {
      text: lang.ssAlignHCenter,
      handler: () => alignElementToCanvas(ElementAlignCommands.HORIZONTAL),
      children: [
        { text: lang.ssAlignHVCenter, handler: () => alignElementToCanvas(ElementAlignCommands.CENTER), },
        { text: lang.ssAlignHCenter, handler: () => alignElementToCanvas(ElementAlignCommands.HORIZONTAL) },
        { text: lang.ssAlignLeft, handler: () => alignElementToCanvas(ElementAlignCommands.LEFT) },
        { text: lang.ssAlignRight, handler: () => alignElementToCanvas(ElementAlignCommands.RIGHT) },
      ],
    },
    {
      text: lang.ssAlignVCenter,
      handler: () => alignElementToCanvas(ElementAlignCommands.VERTICAL),
      children: [
        { text: lang.ssAlignHVCenter, handler: () => alignElementToCanvas(ElementAlignCommands.CENTER) },
        { text: lang.ssAlignVCenter, handler: () => alignElementToCanvas(ElementAlignCommands.VERTICAL) },
        { text: lang.ssAlignTop, handler: () => alignElementToCanvas(ElementAlignCommands.TOP) },
        { text: lang.ssAlignBottom, handler: () => alignElementToCanvas(ElementAlignCommands.BOTTOM) },
      ],
    },
    { divider: true },
    {
      text: lang.ssBringFront,
      disable: props.isMultiSelect && !props.elementInfo.groupId,
      handler: () => orderElement(props.elementInfo, ElementOrderCommands.TOP),
      children: [
        { text: lang.ssBringFront, handler: () => orderElement(props.elementInfo, ElementOrderCommands.TOP) },
        { text: lang.ssBringForward, handler: () => orderElement(props.elementInfo, ElementOrderCommands.UP) },
      ],
    },
    {
      text: lang.ssSendBack,
      disable: props.isMultiSelect && !props.elementInfo.groupId,
      handler: () => orderElement(props.elementInfo, ElementOrderCommands.BOTTOM),
      children: [
        { text: lang.ssSendBack, handler: () => orderElement(props.elementInfo, ElementOrderCommands.BOTTOM) },
        { text: lang.ssSendBackward, handler: () => orderElement(props.elementInfo, ElementOrderCommands.DOWN) },
      ],
    },
    { divider: true },
    {
      text: lang.ssSetLink,
      handler: props.openLinkDialog,
    },
    {
      text: props.elementInfo.groupId ? lang.ssUngroupEl : lang.ssGroupEl,
      subText: 'Ctrl + G',
      handler: props.elementInfo.groupId ? uncombineElements : combineElements,
      hide: !props.isMultiSelect,
    },
    {
      text: lang.ssSelectAll,
      subText: 'Ctrl + A',
      handler: selectAllElements,
    },
    {
      text: lang.ssLock,
      subText: 'Ctrl + L',
      handler: lockElement,
    },
    {
      text: lang.ssDelete,
      subText: 'Delete',
      handler: deleteElement,
    },
  ]

  // 为网页元素添加特殊菜单项
  if (props.elementInfo.type === ElementTypes.FRAME) {
    const frameMenu = [
      {
        text: lang.ssOpenNewWin,
        handler: () => {
          const frameElement = props.elementInfo as any
          if (frameElement.url) {
            window.open(frameElement.url, '_blank')
          }
        },
      },
      {
        text: lang.ssCopyLink,
        handler: () => {
          const frameElement = props.elementInfo as any
          if (frameElement.url) {
            navigator.clipboard.writeText(frameElement.url)
          }
        },
      },
      { divider: true },
    ]
    // 为网页元素过滤掉"设置链接"功能
    const filteredBaseMenu = baseMenu.filter(item => item.text !== lang.ssSetLink)
    return [...frameMenu, ...filteredBaseMenu]
  }

  return baseMenu
}
</script>