<template>
  <n-layout class="menu-management">
    <n-layout-header bordered class="menu-management__header">
      <n-space justify="space-between" align="center">
        <n-h2>菜单管理</n-h2>
        <n-button type="primary" @click="handleAddParent">
          <template #icon>
            <n-icon><PlusOutlined /></n-icon>
          </template>
          添加父级菜单
        </n-button>
      </n-space>
    </n-layout-header>

    <n-layout-content class="menu-management__content">
      <n-spin :show="loading">
        <n-tree
          block-line
          :data="menuTree"
          :render-label="renderTreeLabel"
          :render-switcher-icon="renderSwitcherIcon"
          :expanded-keys="expandedKeys"
          @update:expanded-keys="handleExpand"
        />
      </n-spin>
    </n-layout-content>

    <!-- 父级菜单表单弹窗 -->
    <n-modal v-model:show="showParentModal" preset="dialog" :title="parentModalTitle">
      <n-form
        ref="parentFormRef"
        :model="parentForm"
        :rules="parentRules"
        label-placement="left"
        label-width="auto"
        require-mark-placement="right-hanging"
      >
        <n-form-item label="菜单名称" path="label">
          <n-input v-model:value="parentForm.label" placeholder="请输入菜单名称" />
        </n-form-item>
        <n-form-item label="菜单路径" path="path">
          <n-input v-model:value="parentForm.path" placeholder="请输入菜单路径" />
        </n-form-item>
        <n-form-item label="菜单编码" path="menuCode">
          <n-input v-model:value="parentForm.menuCode" placeholder="请输入菜单编码" />
        </n-form-item>
        <n-form-item label="图标" path="icon">
          <n-input v-model:value="parentForm.icon" placeholder="请输入图标名称" />
        </n-form-item>
        <n-form-item label="组件路径" path="component">
          <n-input v-model:value="parentForm.component" placeholder="请输入组件路径" />
        </n-form-item>
        <n-form-item label="适配方式" path="adaptability">
          <n-select
            v-model:value="parentForm.adaptability"
            :options="adaptabilityOptions"
            placeholder="请选择适配方式"
          />
        </n-form-item>
        <n-form-item label="排序" path="sort">
          <n-input-number v-model:value="parentForm.sort" :min="0" />
        </n-form-item>
        <n-form-item label="状态" path="status">
          <n-radio-group v-model:value="parentForm.status">
            <n-space>
              <n-radio value="enabled">启用</n-radio>
              <n-radio value="disabled">禁用</n-radio>
            </n-space>
          </n-radio-group>
        </n-form-item>
        <n-form-item label="查询参数" path="query">
          <n-input
            v-model:value="parentForm.query"
            type="textarea"
            placeholder="请输入查询参数(JSON格式)"
          />
        </n-form-item>
      </n-form>
      <template #action>
        <n-space justify="end">
          <n-button @click="showParentModal = false">取消</n-button>
          <n-button type="primary" @click="handleSubmitParent">确认</n-button>
        </n-space>
      </template>
    </n-modal>

    <!-- 子级菜单表单弹窗 -->
    <n-modal v-model:show="showChildModal" preset="dialog" :title="childModalTitle">
      <n-form
        ref="childFormRef"
        :model="childForm"
        :rules="childRules"
        label-placement="left"
        label-width="auto"
        require-mark-placement="right-hanging"
      >
        <n-form-item label="父级菜单" path="parentId">
          <n-select
            v-model:value="childForm.parentId"
            :options="parentMenuOptions"
            placeholder="请选择父级菜单"
            :disabled="isEditChild"
          />
        </n-form-item>
        <n-form-item label="菜单名称" path="label">
          <n-input v-model:value="childForm.label" placeholder="请输入菜单名称" />
        </n-form-item>
        <n-form-item label="菜单路径" path="path">
          <n-input v-model:value="childForm.path" placeholder="请输入菜单路径" />
        </n-form-item>
        <n-form-item label="菜单编码" path="menuCode">
          <n-input v-model:value="childForm.menuCode" placeholder="请输入菜单编码" />
        </n-form-item>
        <n-form-item label="图标" path="icon">
          <n-input v-model:value="childForm.icon" placeholder="请输入图标名称" />
        </n-form-item>
        <n-form-item label="组件路径" path="component">
          <n-input v-model:value="childForm.component" placeholder="请输入组件路径" />
        </n-form-item>
        <n-form-item label="适配方式" path="adaptability">
          <n-select
            v-model:value="childForm.adaptability"
            :options="adaptabilityOptions"
            placeholder="请选择适配方式"
          />
        </n-form-item>
        <n-form-item label="排序" path="sort">
          <n-input-number v-model:value="childForm.sort" :min="0" />
        </n-form-item>
        <n-form-item label="状态" path="status">
          <n-radio-group v-model:value="childForm.status">
            <n-space>
              <n-radio value="enabled">启用</n-radio>
              <n-radio value="disabled">禁用</n-radio>
            </n-space>
          </n-radio-group>
        </n-form-item>
        <n-form-item label="查询参数" path="query">
          <n-input
            v-model:value="childForm.query"
            type="textarea"
            placeholder="请输入查询参数(JSON格式)"
          />
        </n-form-item>
      </n-form>
      <template #action>
        <n-space justify="end">
          <n-button @click="showChildModal = false">取消</n-button>
          <n-button type="primary" @click="handleSubmitChild">确认</n-button>
        </n-space>
      </template>
    </n-modal>
  </n-layout>
</template>

<script setup lang="ts">
// 首先确保已安装 @vicons/ionicons5
import { Add, Create, Trash, Document, FolderOpen, Folder } from '@vicons/ionicons5'
import {
  addParentMenu,
  editParentMenu,
  addChildMenu,
  eidtChildMenu,
  getAllMenu,
  deleteMenu,
  type MenuTree,
  type MenuNode,
  type RawMenu
} from '@/api/menu'
import { FormInst, FormRules, NButton, NIcon, NSpace, SelectOption, TreeOption } from 'naive-ui'

// 状态管理
const loading = ref(false)
const menuTree = ref<MenuTree[]>([])
const expandedKeys = ref<string[]>([])

// 父级菜单表单相关
const showParentModal = ref(false)
const parentFormRef = ref<FormInst | null>(null)
const parentForm = ref<Omit<RawMenu, 'uuid' | 'parentId'>>({
  path: '',
  label: '',
  icon: '',
  menuCode: '',
  adaptability: 'pc',
  component: '',
  sort: 0,
  status: 'enabled',
  query: ''
})
const parentRules: FormRules = {
  label: { required: true, message: '请输入菜单名称', trigger: 'blur' },
  path: { required: true, message: '请输入菜单路径', trigger: 'blur' },
  menuCode: { required: true, message: '请输入菜单编码', trigger: 'blur' }
}
const isEditParent = ref(false)
const currentParentId = ref('')

// 子级菜单表单相关
const showChildModal = ref(false)
const childFormRef = ref<FormInst | null>(null)
const childForm = ref<Omit<RawMenu, 'uuid'>>({
  parentId: '',
  path: '',
  label: '',
  icon: '',
  menuCode: '',
  adaptability: 'pc',
  component: '',
  sort: 0,
  status: 'enabled',
  query: ''
})
const childRules: FormRules = {
  parentId: { required: true, message: '请选择父级菜单', trigger: 'blur' },
  label: { required: true, message: '请输入菜单名称', trigger: 'blur' },
  path: { required: true, message: '请输入菜单路径', trigger: 'blur' },
  menuCode: { required: true, message: '请输入菜单编码', trigger: 'blur' }
}
const isEditChild = ref(false)
const currentChildId = ref('')

// 适配方式选项
const adaptabilityOptions = [
  { label: 'PC端', value: 'pc' },
  { label: '移动端', value: 'mobile' },
  { label: '响应式', value: 'responsive' }
]

// 计算属性
const parentModalTitle = computed(() => (isEditParent.value ? '编辑父级菜单' : '添加父级菜单'))
const childModalTitle = computed(() => (isEditChild.value ? '编辑子级菜单' : '添加子级菜单'))

// 父级菜单选项
const parentMenuOptions = computed<SelectOption[]>(() => {
  return menuTree.value.map(menu => ({
    label: menu.label,
    value: menu.uuid
  }))
})

// 生命周期钩子
onMounted(() => {
  fetchMenuData()
})

// 方法
const fetchMenuData = async () => {
  try {
    loading.value = true
    const res = await getAllMenu()
    menuTree.value = res
    // 默认展开所有节点
    expandedKeys.value = getAllKeys(res)
  } catch (error) {
    console.error('获取菜单数据失败:', error)
  } finally {
    loading.value = false
  }
}

const getAllKeys = (tree: MenuTree[]): string[] => {
  let keys: string[] = []
  tree.forEach(node => {
    keys.push(node.uuid)
    if (node.children && node.children.length > 0) {
      keys = keys.concat(getAllKeys(node.children as MenuTree[]))
    }
  })
  return keys
}

const handleExpand = (keys: string[]) => {
  expandedKeys.value = keys
}

const handleAddParent = () => {
  isEditParent.value = false
  parentForm.value = {
    path: '',
    label: '',
    icon: '',
    menuCode: '',
    adaptability: 'pc',
    component: '',
    sort: 0,
    status: 'enabled',
    query: ''
  }
  showParentModal.value = true
}

const handleEditParent = (menu: MenuTree) => {
  isEditParent.value = true
  currentParentId.value = menu.uuid
  parentForm.value = {
    path: menu.path,
    label: menu.label,
    icon: menu.icon,
    menuCode: menu.menuCode,
    adaptability: menu.adaptability,
    component: menu.component,
    sort: menu.sort,
    status: menu.status,
    query: menu.query
  }
  showParentModal.value = true
}

const handleSubmitParent = () => {
  parentFormRef.value?.validate(async errors => {
    if (!errors) {
      try {
        if (isEditParent.value) {
          await editParentMenu({
            uuid: currentParentId.value,
            ...parentForm.value
          })
        } else {
          await addParentMenu(parentForm.value)
        }
        showParentModal.value = false
        await fetchMenuData()
      } catch (error) {
        console.error('操作失败:', error)
      }
    }
  })
}

const handleAddChild = (parentId: string) => {
  isEditChild.value = false
  childForm.value = {
    parentId,
    path: '',
    label: '',
    icon: '',
    menuCode: '',
    adaptability: 'pc',
    component: '',
    sort: 0,
    status: 'enabled',
    query: ''
  }
  showChildModal.value = true
}

const handleEditChild = (menu: MenuNode) => {
  isEditChild.value = true
  currentChildId.value = menu.uuid
  childForm.value = {
    parentId: menu.parentId,
    path: menu.path,
    label: menu.label,
    icon: menu.icon,
    menuCode: menu.menuCode,
    adaptability: menu.adaptability,
    component: menu.component,
    sort: menu.sort,
    status: menu.status,
    query: menu.query
  }
  showChildModal.value = true
}

const handleSubmitChild = () => {
  childFormRef.value?.validate(async errors => {
    if (!errors) {
      try {
        if (isEditChild.value) {
          await eidtChildMenu({
            uuid: currentChildId.value,
            ...childForm.value
          })
        } else {
          await addChildMenu(childForm.value)
        }
        showChildModal.value = false
        await fetchMenuData()
      } catch (error) {
        console.error('操作失败:', error)
      }
    }
  })
}

const handleDelete = async (uuid: string) => {
  try {
    await deleteMenu(uuid)
    await fetchMenuData()
  } catch (error) {
    console.error('删除失败:', error)
  }
}

const renderTreeLabel = ({ option }: { option: TreeOption }) => {
  const menu = option as unknown as MenuTree | MenuNode
  return h('div', { class: 'menu-management__tree-node' }, [
    h('span', { class: 'menu-management__tree-label' }, menu.label),
    h(NSpace, { class: 'menu-management__tree-actions' }, {
      default: () => [
        !option.isLeaf 
          ? h(NButton, {
              size: 'tiny',
              tertiary: true,
              onClick: (e: MouseEvent) => {
                e.stopPropagation()
                handleAddChild(menu.uuid)
              }
            }, {
              icon: () => h(NIcon, { size: 14 }, () => h(Add))
            })
          : null,
        h(NButton, {
          size: 'tiny',
          tertiary: true,
          onClick: (e: MouseEvent) => {
            e.stopPropagation()
            if (menu.parentId === null) {
              handleEditParent(menu as MenuTree)
            } else {
              handleEditChild(menu as MenuNode)
            }
          }
        }, {
          icon: () => h(NIcon, { size: 14 }, () => h(Create))
        }),
        h(NButton, {
          size: 'tiny',
          tertiary: true,
          type: 'error',
          onClick: (e: MouseEvent) => {
            e.stopPropagation()
            handleDelete(menu.uuid)
          }
        }, {
          icon: () => h(NIcon, { size: 14 }, () => h(Trash))
        })
      ]
    })
  ])
}

// 自定义切换图标渲染
const renderSwitcherIcon = ({ expanded, option }: { expanded: boolean; option: TreeOption }) => {
  return h(NIcon, { size: 16 }, () => 
    option.isLeaf 
      ? h(Document)
      : expanded 
        ? h(FolderOpen)
        : h(Folder)
  )
}
</script>

<style lang="scss" scoped>
.menu-management {
  height: 100vh;
  display: flex;
  flex-direction: column;

  &__header {
    padding: 16px 24px;
    background-color: var(--n-color);
  }

  &__content {
    padding: 20px;
    flex: 1;
    overflow: auto;
  }

  &__tree-node {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 4px 0;

    &:hover {
      .menu-management__tree-actions {
        opacity: 1;
      }
    }
  }

  &__tree-label {
    flex: 1;
    margin-right: 8px;
  }

  &__tree-actions {
    opacity: 0;
    transition: opacity 0.2s ease-in-out;
  }
}
</style>