<template>
  <div class="container">
    <Breadcrumb :items="['menu.ops.systemSettings', 'menu.ops.systemSettings.menuManagement']" />
    <a-row :gutter="16" class="menu-container">
      <!-- 左侧: 菜单树 -->
      <a-col :xs="24" :md="10" :lg="8">
        <a-card class="menu-tree-card" :bordered="false">
          <!-- 头部操作区 -->
          <template #title>
            <div class="card-header">
              <span>菜单管理</span>
              <a-button type="primary" size="small" @click="handleAddRootMenu">
                <template #icon><icon-plus /></template>
                添加根菜单
              </a-button>
            </div>
          </template>
          
          <!-- 提示信息 -->
          <a-alert class="menu-tip" type="info" :show-icon="true">
            点击菜单项可编辑，悬停显示操作按钮
          </a-alert>
          
          <!-- 菜单树 -->
          <a-spin :loading="loading" class="menu-tree-spin">
            <div class="menu-tree-wrapper">
              <MenuTree
                v-if="rootItems.length > 0"
                :nodes="rootItems"
                :expanded-keys="expandedKeys"
                :selected-key="selectedNode?.id || null"
                :dragging-node="draggingNode"
                @toggle="handleToggleExpand"
                @select="handleSelectNode"
                @add-child="handleAddChildMenu"
                @delete="handleDeleteClick"
                @drag-start="handleDragStart"
                @drag-end="handleDragEnd"
                @drop="handleDrop"
              />
              <a-empty v-else description="暂无菜单数据" />
            </div>
          </a-spin>
        </a-card>
      </a-col>
      
      <!-- 右侧: 编辑表单 -->
      <a-col :xs="24" :md="14" :lg="16">
        <a-card class="menu-edit-card" :bordered="false">
          <template #title>
            <div class="edit-header">
              <span>{{ getEditTitle() }}</span>
              <span v-if="isAddingChild || (isEditing && selectedNode?.parent_id)" class="parent-info">
                父菜单: 
                <a-tag color="arcoblue">
                  {{ isEditing && selectedNode?.parent_id ? getParentMenuName(selectedNode.parent_id) : getParentMenuName(parentId) }}
                </a-tag>
              </span>
            </div>
          </template>
          
          <!-- 编辑表单 -->
          <MenuForm
            v-if="isEditing || isAdding || isAddingChild"
            :mode="getEditMode()"
            :parent-id="parentId"
            :initial-values="selectedNode"
            :parent-name="getParentMenuName(parentId)"
            @save="handleSaveMenu"
            @cancel="handleCancelEdit"
          />
          
          <a-empty v-else description="请从左侧选择一个菜单项进行编辑" class="empty-state" />
        </a-card>
      </a-col>
    </a-row>
    
    <!-- 删除确认对话框 -->
    <a-modal
      v-model:visible="deleteConfirmVisible"
      title="删除确认"
      @ok="handleConfirmDelete"
      @cancel="deleteConfirmVisible = false"
    >
      <p>确定要删除菜单 "{{ nodeToDelete?.title }}" 吗？</p>
      <p v-if="nodeToDelete?.children?.length" class="warning-text">
        <icon-exclamation-circle-fill /> 注意：该菜单下有子菜单，删除后子菜单也会被删除！
      </p>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, onMounted } from 'vue'
import { Message } from '@arco-design/web-vue'
import type { MenuNode, MenuRouteRequest } from './types'
import { fetchMenu, createMenu, modifyMenu, deleteMenu, updateMenuOrder } from '@/api/module/pmn'
import { buildTree } from '@/utils/tree'
import MenuTree from './components/MenuTree.vue'
import MenuForm from './components/MenuForm.vue'

// 状态管理
const loading = ref(false)
const menuItems = ref<MenuRouteRequest[]>([])
const expandedKeys = ref<Set<number>>(new Set())
const selectedNode = ref<MenuNode | null>(null)

// 编辑状态
const isEditing = ref(false)
const isAdding = ref(false)
const isAddingChild = ref(false)
const parentId = ref<number | null>(null)

// 删除确认
const deleteConfirmVisible = ref(false)
const nodeToDelete = ref<MenuNode | null>(null)

// 拖拽状态
const draggingNode = ref<MenuNode | null>(null)

// 计算属性 - 使用公共 buildTree 函数构建树
const treeData = computed(() => buildTree<MenuNode>(menuItems.value as MenuNode[], { orderKey: 'order' }))
const rootItems = computed(() => treeData.value.rootItems)
const itemMap = computed(() => treeData.value.itemMap)

// 加载菜单数据
const loadMenuItems = async () => {
  try {
    loading.value = true
    const res = await fetchMenu({ page: 1, size: 10000 })
    if (res?.code === 0) {
      menuItems.value = res.details?.data || []
    }
  } catch (error) {
    console.error('Failed to load menu items:', error)
  } finally {
    loading.value = false
  }
}

// 切换节点展开/折叠
const handleToggleExpand = (nodeId: number) => {
  if (expandedKeys.value.has(nodeId)) {
    expandedKeys.value.delete(nodeId)
  } else {
    expandedKeys.value.add(nodeId)
  }
}

// 选择节点
const handleSelectNode = (node: MenuNode) => {
  selectedNode.value = node
  isEditing.value = true
  isAdding.value = false
  isAddingChild.value = false
}

// 添加根菜单
const handleAddRootMenu = () => {
  selectedNode.value = null
  isEditing.value = false
  isAdding.value = true
  isAddingChild.value = false
  parentId.value = null
}

// 添加子菜单
const handleAddChildMenu = (pId: number) => {
  selectedNode.value = null
  isEditing.value = false
  isAdding.value = false
  isAddingChild.value = true
  parentId.value = pId
}

// 编辑菜单
const handleEditMenu = (node: MenuNode) => {
  selectedNode.value = node
  isEditing.value = true
  isAdding.value = false
  isAddingChild.value = false
  parentId.value = node.parent_id || null
}

// 删除点击
const handleDeleteClick = (node: MenuNode) => {
  nodeToDelete.value = node
  deleteConfirmVisible.value = true
}

// 确认删除
const handleConfirmDelete = async () => {
  if (!nodeToDelete.value?.id) return
  
  try {
    loading.value = true
    await deleteMenu({ id: nodeToDelete.value.id })
    Message.success('删除成功')
    
    // 如果删除的是当前选中的节点，清空编辑状态
    if (selectedNode.value?.id === nodeToDelete.value.id) {
      selectedNode.value = null
      isEditing.value = false
      isAdding.value = false
      isAddingChild.value = false
      parentId.value = null
    }
    
    deleteConfirmVisible.value = false
    nodeToDelete.value = null
    await loadMenuItems()
  } catch (error) {
    console.error('Failed to delete menu:', error)
  } finally {
    loading.value = false
  }
}

// 保存菜单
const handleSaveMenu = async (menuData: MenuRouteRequest) => {
  try {
    loading.value = true
    if (isEditing.value && selectedNode.value?.id) {
      await modifyMenu({ ...menuData, id: selectedNode.value.id })
    } else {
      await createMenu(menuData)
    }
    Message.success('保存成功')
    
    // 重置状态
    isEditing.value = false
    isAdding.value = false
    isAddingChild.value = false
    await loadMenuItems()
  } catch (error) {
    console.error('Failed to save menu:', error)
  } finally {
    loading.value = false
  }
}

// 取消编辑
const handleCancelEdit = () => {
  isEditing.value = false
  isAdding.value = false
  isAddingChild.value = false
  selectedNode.value = null
}

// 获取编辑模式
const getEditMode = (): 'add' | 'edit' | 'add_child' => {
  if (isEditing.value) return 'edit'
  if (isAddingChild.value) return 'add_child'
  return 'add'
}

// 获取编辑区标题
const getEditTitle = () => {
  if (isEditing.value && selectedNode.value) {
    return `编辑: ${selectedNode.value.title}`
  }
  if (isAddingChild.value) {
    const parentName = getParentMenuName(parentId.value)
    return `为 "${parentName}" 添加子菜单`
  }
  if (isAdding.value) return '添加根菜单'
  return '详情'
}

// 获取父菜单名称
const getParentMenuName = (pId?: number | null) => {
  const map = itemMap.value
  if (!pId || !map.has(pId)) return ''
  const item = map.get(pId)
  return item?.title || ''
}

// 拖拽开始
const handleDragStart = (node: MenuNode) => {
  draggingNode.value = node
}

// 拖拽结束
const handleDragEnd = () => {
  draggingNode.value = null
}

// 处理放置
const handleDrop = async (data: { dragNode: MenuNode; targetNode: MenuNode; position: 'before' | 'after' | 'inside' }) => {
  const { dragNode, targetNode, position } = data
  
  if (!dragNode.id) return
  
  try {
    loading.value = true
    
    if (position === 'inside') {
      // 拖放到某个节点内部，成为其子节点
      const { children, ...dragData } = dragNode
      await modifyMenu({ 
        ...dragData, 
        parent_id: targetNode.id 
      } as MenuRouteRequest)
    } else {
      // 拖放到某个节点前后，需要更新排序
      const sortList: { pmn_id: number; sort_key: number }[] = []
      let sortKey = 1
      
      // 获取同级节点
      const siblings = menuItems.value
        .filter(item => item.parent_id === targetNode.parent_id)
        .sort((a, b) => (a.order || 0) - (b.order || 0))
      
      // 找到拖拽节点和目标节点的索引
      const dragIndex = siblings.findIndex(item => item.id === dragNode.id)
      const targetIndex = siblings.findIndex(item => item.id === targetNode.id)
      
      // 检查是否需要移动
      const isSameParent = dragNode.parent_id === targetNode.parent_id
      const isAlreadyBefore = isSameParent && dragIndex === targetIndex - 1
      const isAlreadyAfter = isSameParent && dragIndex === targetIndex + 1
      
      // 如果已经在目标位置，不需要更新排序
      const needSort = !(isSameParent && (
        (position === 'before' && dragIndex === targetIndex) ||
        (position === 'before' && isAlreadyBefore) ||
        (position === 'after' && dragIndex === targetIndex) ||
        (position === 'after' && isAlreadyAfter)
      ))
      
      if (needSort) {
        siblings.forEach((item) => {
          if (item.id === targetNode.id) {
            if (position === 'before') {
              sortList.push({ pmn_id: dragNode.id!, sort_key: sortKey++ })
              sortList.push({ pmn_id: item.id!, sort_key: sortKey++ })
            } else {
              sortList.push({ pmn_id: item.id!, sort_key: sortKey++ })
              sortList.push({ pmn_id: dragNode.id!, sort_key: sortKey++ })
            }
          } else if (item.id !== dragNode.id) {
            sortList.push({ pmn_id: item.id!, sort_key: sortKey++ })
          }
        })
      }
      
      // 更新拖拽节点的 parent_id
      const { children, ...dragData } = dragNode
      await modifyMenu({ 
        ...dragData, 
        parent_id: targetNode.parent_id || null
      } as MenuRouteRequest)
      
      // 更新排序
      if (sortList.length > 0) {
        await updateMenuOrder(sortList)
      }
    }
    
    Message.success('移动成功')
    await loadMenuItems()
  } catch (error) {
    console.error('Failed to move menu:', error)
    Message.error('移动失败')
  } finally {
    loading.value = false
    draggingNode.value = null
  }
}

// 递归收集子节点
const collectChildren = (
  items: MenuRouteRequest[], 
  parentId: number, 
  sortList: { pmn_id: number; sort_key: number }[], 
  getSortKey: () => number
) => {
  const children = items
    .filter((item: MenuRouteRequest) => item.parent_id === parentId)
    .sort((a: MenuRouteRequest, b: MenuRouteRequest) => (a.order || 0) - (b.order || 0))
  
  children.forEach((item: MenuRouteRequest) => {
    if (item.id) {
      sortList.push({ pmn_id: item.id, sort_key: getSortKey() })
      collectChildren(items, item.id, sortList, getSortKey)
    }
  })
}

// 初始加载
onMounted(() => {
  loadMenuItems()
})
</script>

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

<style scoped lang="less">
.container {
  padding: 0 20px 20px 20px;
}

.menu-container {
  height: calc(100vh - 300px);
  > div {
    height: 100%;
  }
}

.menu-tree-card,
.menu-edit-card {
  height: 100%;
  display: flex;
  flex-direction: column;
  
  :deep(.arco-card-body) {
    flex: 1;
    overflow: hidden;
    display: flex;
    flex-direction: column;
  }
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
}

.menu-tip {
  margin-bottom: 16px;
}

.menu-tree-spin {
  flex: 1;
  overflow: hidden;
}

.menu-tree-wrapper {
  height: 100%;
  overflow-y: auto;
  padding-right: 8px;
}

.edit-header {
  display: flex;
  align-items: center;
  gap: 12px;
  
  .parent-info {
    font-size: 12px;
    color: var(--color-text-3);
    font-weight: normal;
  }
}

.empty-state {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.warning-text {
  color: rgb(var(--warning-6));
  margin-top: 8px;
}
</style>
