<template>
  <div class="menu-tree-item">
    <div
      class="menu-item-content"
      :class="{
        'is-selected': selectedKey === node.id,
        'is-hovered': isHovered,
        'drag-over': isDragOver,
      }"
      :style="{ paddingLeft: `${level * 16}px` }"
      draggable="true"
      @click="handleSelect"
      @mouseenter="isHovered = true"
      @mouseleave="isHovered = false"
      @dragstart="handleDragStart"
      @dragover="handleDragOver"
      @dragleave="handleDragLeave"
      @drop="handleDrop"
      @dragend="handleDragEnd"
    >
      <!-- 展开/折叠按钮 -->
      <span class="expand-btn" @click.stop="handleToggle">
        <icon-right v-if="!isExpanded && hasChildren" />
        <icon-down v-else-if="isExpanded && hasChildren" />
        <span v-else class="placeholder"></span>
      </span>

      <!-- 拖拽手柄 -->
      <span class="drag-handle">
        <icon-drag-dot-vertical />
      </span>

      <!-- 菜单图标 -->
      <span v-if="node.menu_icon" class="menu-icon">
        <component :is="getIcon(node.menu_icon)" />
      </span>

      <!-- 菜单标题 -->
      <span class="menu-title">{{ node.title }}</span>

      <!-- 分组标识 -->
      <a-tag v-if="!node.menu_path" size="small" color="gray">分组</a-tag>

      <!-- 操作按钮 -->
      <span v-show="isHovered" class="action-btns">
        <!-- 只有一级菜单（根菜单）才显示添加按钮 -->
        <a-tooltip v-if="level === 1" content="添加子菜单">
          <a-button type="text" size="mini" @click.stop="handleAddChild">
            <template #icon><icon-plus /></template>
          </a-button>
        </a-tooltip>
        <a-tooltip content="删除">
          <a-button type="text" size="mini" status="danger" @click.stop="handleDelete">
            <template #icon><icon-delete /></template>
          </a-button>
        </a-tooltip>
      </span>
    </div>

    <!-- 子菜单 -->
    <div v-if="isExpanded && hasChildren" class="menu-children">
      <MenuTreeItem
        v-for="child in node.children"
        :key="child.id"
        :node="child"
        :level="level + 1"
        :expanded-keys="expandedKeys"
        :selected-key="selectedKey"
        :dragging-node="draggingNode"
        @toggle="$emit('toggle', $event)"
        @select="$emit('select', $event)"
        @add-child="$emit('add-child', $event)"
        @delete="$emit('delete', $event)"
        @drag-start="$emit('drag-start', $event)"
        @drag-end="$emit('drag-end')"
        @drop="$emit('drop', $event)"
      />
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue'
import type { MenuNode } from '../types'
import { getIconComponent } from '../menuIcons'

const props = defineProps<{
  node: MenuNode
  level: number
  expandedKeys: Set<number>
  selectedKey: number | null
  draggingNode?: MenuNode | null
}>()

const emit = defineEmits<{
  (e: 'toggle', nodeId: number): void
  (e: 'select', node: MenuNode): void
  (e: 'add-child', parentId: number): void
  (e: 'delete', node: MenuNode): void
  (e: 'drag-start', node: MenuNode): void
  (e: 'drag-end'): void
  (e: 'drop', data: { dragNode: MenuNode; targetNode: MenuNode; position: 'before' | 'after' | 'inside' }): void
}>()

const isHovered = ref(false)
const isDragOver = ref(false)

const isExpanded = computed(() => props.expandedKeys.has(props.node.id))
const hasChildren = computed(() => props.node.children && props.node.children.length > 0)
const isDraggingThis = computed(() => props.draggingNode?.id === props.node.id)

const handleToggle = () => {
  if (hasChildren.value) {
    emit('toggle', props.node.id)
  }
}

const handleSelect = () => {
  emit('select', props.node)
}

const handleAddChild = () => {
  emit('add-child', props.node.id)
}

const handleDelete = () => {
  emit('delete', props.node)
}

// 拖拽相关
const handleDragStart = (e: DragEvent) => {
  e.dataTransfer!.effectAllowed = 'move'
  emit('drag-start', props.node)
  // 添加拖拽样式
  const target = e.target as HTMLElement
  setTimeout(() => {
    target.style.opacity = '0.5'
  }, 0)
}

const handleDragOver = (e: DragEvent) => {
  e.preventDefault()
  e.dataTransfer!.dropEffect = 'move'
  isDragOver.value = true
}

const handleDragLeave = () => {
  isDragOver.value = false
}

const handleDrop = (e: DragEvent) => {
  e.preventDefault()
  isDragOver.value = false

  if (props.draggingNode && props.draggingNode.id !== props.node.id) {
    // 判断放置位置
    const rect = (e.target as HTMLElement).getBoundingClientRect()
    const y = e.clientY - rect.top
    const height = rect.height

    let position: 'before' | 'after' | 'inside' = 'inside'
    if (y < height * 0.25) {
      position = 'before'
    } else if (y > height * 0.75) {
      position = 'after'
    } else {
      position = 'inside'
    }

    emit('drop', {
      dragNode: props.draggingNode,
      targetNode: props.node,
      position,
    })
  }
}

const handleDragEnd = (e: DragEvent) => {
  const target = e.target as HTMLElement
  target.style.opacity = '1'
  emit('drag-end')
}

// 获取图标组件
const getIcon = (iconName: string) => {
  return getIconComponent(iconName)
}
</script>

<script lang="ts">
export default {
  name: 'MenuTreeItem',
}
</script>

<style scoped lang="less">
.menu-tree-item {
  .menu-item-content {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s;
    border: 2px solid transparent;

    &:hover,
    &.is-hovered {
      background-color: var(--color-fill-2);
    }

    &.is-selected {
      background-color: rgb(var(--primary-1));
      color: rgb(var(--primary-6));
    }

    &.drag-over {
      border-color: rgb(var(--primary-6));
      background-color: rgb(var(--primary-1));
    }

    .expand-btn {
      width: 16px;
      height: 16px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-right: 4px;
      color: var(--color-text-3);

      .placeholder {
        width: 16px;
        height: 16px;
      }
    }

    .drag-handle {
      width: 16px;
      height: 16px;
      display: flex;
      align-items: center;
      justify-content: center;
      margin-right: 4px;
      color: var(--color-text-4);
      cursor: grab;

      &:hover {
        color: var(--color-text-2);
      }
    }

    .menu-icon {
      margin-right: 8px;
      color: var(--color-text-2);
    }

    .menu-title {
      flex: 1;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      font-size: 14px;
    }

    .action-btns {
      display: flex;
      gap: 4px;
    }
  }

  .menu-children {
    // 子菜单样式
  }
}
</style>
