<template>
  <div id="category-tree" class="p-2 bg-white">
    <p>类目展示：</p>
    <el-tree
      style="max-width: 600px"
      :data="dataSource"
      node-key="id"
      draggable
      default-expand-all
      :expand-on-click-node="false"
      @node-drag-start="handleDragStart"
      @node-drag-enter="handleDragEnter"
      @node-drag-leave="handleDragLeave"
      @node-drag-over="handleDragOver"
      @node-drag-end="handleDragEnd"
      @node-drop="handleDrop"
    >
      <template #default="{ node, data }">
        <div class="category-tree-node">
          <span v-if="curId !== data.id">{{ data.label }}</span>
          <el-input
            ref="inputRef"
            v-else
            v-model="data.label2"
            size="small"
            class="w-40"
            @keyup.enter="handleInputConfirm(data)"
            @blur="handleInputCancel(node, data)"
          />
          <div>
            <el-button type="primary" link @click="edit(data)" size="small">编辑 </el-button>
            <el-button type="primary" link @click="append(data)" size="small"> 添加 </el-button>
            <el-button type="danger" size="small" link @click="remove(node, data)">
              删除
            </el-button>
          </div>
        </div>
      </template>
    </el-tree>
  </div>
</template>

<script lang="ts" setup>
import { ElButton } from 'element-plus'
import type { RenderContentContext } from 'element-plus'
import { dataSource } from './mock'
import {
  handleDragStart,
  handleDragEnter,
  handleDragOver,
  handleDragLeave,
  handleDragEnd,
  handleDrop
} from './use-drag'

interface Tree {
  id: number
  label: string
  children?: Tree[]
}
type Node = RenderContentContext['node']
type Data = RenderContentContext['data']

const curId = ref(NaN)
const inputRef = ref()

const edit = (data: Data) => {
  data.label2 = data.label
  curId.value = data.id
  nextTick(() => {
    inputRef.value.focus()
  })
}

// 回车确认
const handleInputConfirm = (data: any) => {
  if (curId.value === Infinity) {
    // 新增接口
  } else {
    // 修改接口
  }
  data.label = data.label2
  data.label2 = ''
  curId.value = NaN
}

// 失焦
const handleInputCancel = (node: Node, data: Data) => {
  if (data.id === Infinity) {
    remove(node, data)
  }
  curId.value = NaN
}

const append = (data: Data) => {
  curId.value = Infinity
  const newChild = { id: curId.value, label2: 'test', children: [] }
  if (!data.children) {
    data.children = []
  }
  data.children.push(newChild)
  dataSource.value = [...dataSource.value]
  nextTick(() => {
    inputRef.value.focus()
  })
}

const remove = (node: Node, data: Data) => {
  const parent = node.parent
  const children: Tree[] = parent?.data.children || parent?.data
  const index = children.findIndex((d) => d.id === data.id)
  children.splice(index, 1)
  dataSource.value = [...dataSource.value]
}
</script>

<style lang="scss" scoped>
#category-tree {
  .category-tree-node {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    padding-right: 8px;
  }
}
</style>
