<template>
  <div id="category-tree" class="p-2 bg-white">
    <p>
      类目展示：
      <el-input
        v-if="addRootCategory.showInput"
        class="w-20 !h-[22px]"
        v-model="addRootCategory.inputValue"
        ref="addRootCategoryInputRef"
        @keyup.enter="onAddRootCategory"
        @blur="addRootCategory.showInput = false"
      ></el-input>
      <el-button
        v-else
        class="w-20 !h-[22px]"
        type="primary"
        size="small"
        @click="onClickAddRootCategory"
        >添加根类目</el-button
      >
    </p>
    <el-tree
      ref="treeRef"
      :props="defaultProps"
      node-key="id"
      draggable
      :render-after-expand="false"
      check-strictly
      :load="handleLoadNode"
      lazy
      highlight-current
      :expand-on-click-node="false"
      @node-click="handleNodeClick"
      @node-drag-start="handleDragStart"
      @node-drop="handleDropFinish"
    >
      <template #default="{ node, data }">
        <div class="category-tree-node">
          <div class="flex-1">
            <span v-if="editChildCategoryId !== data.id">{{ data.name }}</span>
            <el-input
              ref="editChildCategoryInputRef"
              v-else
              v-model="data.label2"
              size="small"
              class="w-40"
              @keyup.enter="handleEditChildCategoryConfirm(node, data)"
              @blur="editChildCategoryId = NaN"
            />
            <template v-if="data.isProperty">
              <dl class="flex items-center">
                <dt class="text-sm text-[#666] mb-2">
                  【属性】
                  <span v-if="editPropertyTypeId !== data.id">{{ data.categoryPropertyName }}</span>
                  <el-input
                    ref="editPropertyTypeInputRef"
                    v-else
                    v-model="data.label2"
                    size="small"
                    class="w-40"
                    @keyup.enter="handleEditPropertyTypeConfirm(node, data)"
                    @blur="editPropertyTypeId = NaN"
                  />：
                </dt>
                <dd class="flex mb-2 flex-wrap">
                  <div v-for="child in data.vvPropertyValueList" :key="data.id + '-' + child.id">
                    <el-input
                      v-if="curPropertyValueId === child.id"
                      ref="editPropertyValueInputRef"
                      class="w-20"
                      size="small"
                      v-model="inputEditPropertyValue"
                      @keyup.enter="onEditPropertyValue(child)"
                      @blur="curPropertyValueId = NaN"
                    ></el-input>
                    <el-tag
                      v-else
                      closable
                      effect="plain"
                      type="primary"
                      class="mr-1"
                      @click="onClickPropertyValue(child)"
                      @close="onClosePropertyValue(child.id, data)"
                      >{{ child.categoryPropertyValue }}</el-tag
                    >
                  </div>
                  <el-input
                    ref="propertyValueInputRef"
                    class="w-20"
                    size="small"
                    v-if="visiblePropertyValue[data.id]"
                    v-model="inputPropertyValue"
                    @keyup.enter="onAddPropertyValue(data)"
                    @blur="visiblePropertyValue[data.id] = false"
                  ></el-input>
                  <el-button
                    v-else
                    type="primary"
                    size="small"
                    class="ml-2 !text-[10px] !px-2 !py-1 !pb-0.5"
                    @click="onClickPropertyBtn(data)"
                    >新增属性值</el-button
                  >
                  <el-button
                    type="warning"
                    size="small"
                    class="!text-[10px] !px-2 !py-1 !pb-0.5"
                    @click="onEditPropertyType(node, data.id)"
                    >修改属性</el-button
                  >
                  <el-button
                    type="danger"
                    size="small"
                    class="!text-[10px] !px-2 !py-1 !pb-0.5"
                    @click="onDeleteProperty(node, data.id)"
                    >删除属性</el-button
                  >
                </dd>
              </dl>
            </template>
          </div>
          <div v-if="!data.isProperty">
            <template v-if="!data.hasOriginChild">
              <el-input
                ref="propertyTypeInputRef"
                class="w-20"
                size="small"
                v-if="visiblePropertyType[data.id]"
                v-model="inputPropertyTypeValue"
                @keyup.enter="onAddPropertyType(node, data)"
                @blur="visiblePropertyType[data.id] = false"
              ></el-input>
              <el-button
                v-else
                type="success"
                link
                size="small"
                @click="onClickPropertyTypeBtn(data)"
                >新增属性</el-button
              >
            </template>
            <el-button type="primary" link @click="onEdit(data)" size="small">编辑 </el-button>
            <el-input
              ref="addChildCategoryInputRef"
              class="w-20"
              size="small"
              v-if="data.id === addChildCategoryId"
              v-model="childCategoryInputValue"
              @keyup.enter="handleAddChildCategoryConfirm(node, data)"
              @blur="addChildCategoryId = NaN"
            ></el-input>
            <el-button v-else type="warning" link @click="onAppend(node, data)" size="small">
              添加子类目
            </el-button>
            <el-button type="danger" size="small" link @click="onDelete(node)"> 删除 </el-button>
          </div>
        </div>
      </template>
    </el-tree>
  </div>
</template>

<script lang="ts" setup>
import { ElButton, ElMessage } from 'element-plus'
import type { RenderContentContext } from 'element-plus'
import { handleDragStart, handleDropFinish } from './use-drag'
import { handleMessageBox } from '@/utils/page'
import {
  treeRef,
  onEdit,
  onAppend,
  handleAddChildCategoryConfirm,
  handleEditChildCategoryConfirm,
  onDelete,
  editChildCategoryId,
  addChildCategoryId,
  childCategoryInputValue,
  editChildCategoryInputRef,
  addChildCategoryInputRef,
  addRootCategory,
  addRootCategoryInputRef,
  onClickAddRootCategory,
  onAddRootCategory
} from './init-method'

type Node = RenderContentContext['node']
type Data = RenderContentContext['data']

const defaultProps = {
  label: 'name',
  children: 'children',
  disabled: 'disabled',
  isLeaf: (data: any) => {
    return !data.hasChild
  }
}

// 获取类目列表
const handleLoadNode = (node, resolve) => {
  console.warn('----- my data is 222: ', 222)
  if (node.data.vvCategoryPropertyDTOList?.length) {
    resolve(
      node.data.vvCategoryPropertyDTOList.map((item: any) => ({
        ...item,
        hasChild: 0,
        isProperty: 1
      }))
    )
  } else {
    api.commodity.getCategoryList.post!<any>({ parentId: node.data.id || 0 }).then((res) => {
      resolve(
        res.data.map((item: any) => ({
          ...item,
          vvCategoryPropertyDTOList: item.vvCategoryPropertyDTOList || [],
          hasOriginChild: item.hasChild,
          hasChild: item.hasChild || !!item.vvCategoryPropertyDTOList?.length,
          children: item.hasChild ? [] : undefined
        }))
      )
    })
  }
}

const visiblePropertyValue = ref<Record<number, boolean>>({})
const inputPropertyValue = ref('')
const visiblePropertyType = ref<Record<number, boolean>>({})
const inputPropertyTypeValue = ref('')

// 删除类目的属性值
const onClosePropertyValue = async (id: number, data: any) => {
  const i = data.vvPropertyValueList.findIndex((item: any) => item.id === id)
  await api.commodity.deleteCategoryPropertyValue.post!({ id })
  data.vvPropertyValueList.splice(i, 1)
  ElMessage.success('删除成功')
}

// 新增属性值回车确认
const onAddPropertyValue = async (data: any = {}) => {
  if (inputPropertyValue.value) {
    const res = await api.commodity.updateCategoryPropertyValue.post!({
      categoryPropertyId: data.id,
      categoryPropertyValue: inputPropertyValue.value
    })
    data.vvPropertyValueList.push(res.data)
  }
  visiblePropertyValue.value[data.id] = false
  inputPropertyValue.value = ''
  ElMessage.success('新增成功')
}

// 新增属性类型回车确定
const onAddPropertyType = async (node: Node, data: Data) => {
  if (inputPropertyTypeValue.value) {
    const res = await api.commodity.updateCategoryProperty.post!<{
      id: number
      categoryPropertyName: string
    }>({
      categoryId: data.id,
      categoryName: data.name,
      categoryPropertyName: inputPropertyTypeValue.value
    })
    const newData = {
      ...res.data,
      hasChild: 0,
      isProperty: 1,
      vvPropertyValueList: []
    }
    data.vvCategoryPropertyDTOList.push(newData)
    node.loaded = false
    node.expand()
    visiblePropertyType.value[data.id] = false
    inputPropertyTypeValue.value = ''
    ElMessage.success('新增成功')
  }
}

// 删除属性
const onDeleteProperty = async (node: Node, id: number) => {
  handleMessageBox({
    msg: `是否删除属性?`,
    success: api.commodity.deleteCategoryProperty.post!,
    data: { id }
  }).then(() => {
    treeRef.value.remove(node)
  })
}

const propertyTypeInputRef = ref()
// 新增属性类型按钮
const onClickPropertyTypeBtn = (data: any) => {
  visiblePropertyType.value[data.id] = true
  nextTick(() => {
    propertyTypeInputRef.value.input!.focus()
  })
}
const propertyValueInputRef = ref()
// 新增属性值按钮
const onClickPropertyBtn = (data: any) => {
  visiblePropertyValue.value[data.id] = true
  nextTick(() => {
    propertyValueInputRef.value.input!.focus()
  })
}

const curPropertyValueId = ref(NaN)
const inputEditPropertyValue = ref('')
const editPropertyValueInputRef = ref()
// 点击属性值进行编辑
const onClickPropertyValue = (data: any) => {
  curPropertyValueId.value = data.id
  inputEditPropertyValue.value = data.categoryPropertyValue
  nextTick(() => {
    const timer = setTimeout(() => {
      clearTimeout(timer)
      editPropertyValueInputRef.value[0].input!.focus()
    }, 500)
  })
}
// 编辑属性值回车确定
const onEditPropertyValue = async (data: any) => {
  await api.commodity.updateCategoryPropertyValue.post!({
    id: data.id,
    categoryPropertyValue: inputEditPropertyValue.value
  })
  ElMessage.success('编辑成功')
  data.categoryPropertyValue = inputEditPropertyValue.value
  curPropertyValueId.value = NaN
  inputEditPropertyValue.value = ''
}

// 编辑属性类型相关
const editPropertyTypeId = ref(NaN)
const editPropertyTypeInputRef = ref()
const onEditPropertyType = (node: Node, id: number) => {
  editPropertyTypeId.value = id
  nextTick(() => {
    editPropertyTypeInputRef.value.input!.focus()
  })
}
// 编辑属性类型回车确认
const handleEditPropertyTypeConfirm = async (node: Node, data: any) => {
  await api.commodity.updateCategoryProperty.post!({ ...data, categoryPropertyName: data.label2 })
  ElMessage.success('编辑成功')
  data.categoryPropertyName = data.label2
  editPropertyTypeId.value = NaN
}
</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;
  }
  :deep(.el-tree) {
    .el-tree-node__content {
      height: auto;
    }
  }
}
</style>
