<template>
  <div class="ks-tree">
    <div class="top-box">
    <div class="header">
      <span class="header-title">
        <slot />
      </span>
      <Icon
        v-if="showRootAppend"
        class="icon k-icon-add root-append"
        @click="appendToRoot"
      ></Icon>
    </div>
    <Input
      v-if="showSearch"
      clearable
      placeholder="请输入关键字搜索"
      class="search"
      v-model="keywordsRef"
      @clear="onSearch(keywordsRef)"
      @keydown.enter="onSearch(keywordsRef)"
    >
      <template v-slot:suffix
        ><Icon class="k-icon-search" hoverable @click="onSearch(keywordsRef)"
      /></template>
    </Input>
  </div>
    <Tree
      class="tree-box"
      ref="treeRef"
      :draggable="draggable"
      :allowDrag="allowDrag"
      :allowDrop="allowDrop"
      :checkbox="checkbox"
      :selectable="selectable"
      :showLine="showLine"
      :data="dataRef"
      v-model:expandedKeys="localExpandedKeys"
      :filter="filter"
      v-bind="$attrs"
      @denydrag="onDenyDrag"
      @denydrop="onDenyDrop"
      @dragend="onDragEnd"
      @mousedown="itemMousedown"
    >
      <!-- 自定义节点标题内容 -->
      <template v-slot:label="[data, node, index]">
        <slot name="label" v-bind="{ data, node, index }">
          <span class="tree-content">
            <Tooltip :content="data.label" theme="light" :disabled="!data.showTooltip">
              <span
                class="text"
                :class="{'text-disable':isAllDisabled(data)}"
                draggable="false"
                :style="{'text-align':titleAlign}"
                @mousedown.stop
                @mousedown.prevent
                @click="onNodeClick(data, node, index,$event)"
                >
                <span class="inner-text"  @mouseenter="showTooltip($event,data)">
                  {{ data.label }}
                  </span>
                </span
              >
            </Tooltip>
            <span v-show="!data.disabled" class="icon-operation-group"
            @click="onNodeClick(data, node, index,$event)"
            >
              <span
                draggable="false"
                @mousedown.stop
                @mousedown.prevent
                class="no-drag"
                @drag.stop="handleDrag"
              >
              <!-- 优先检测isDisabled控制三个操作按钮，没有则检测其他字段'addDisabled', 'editDisabled', 'deleteDisabled' -->
                <Icon
                  class="icon k-icon-add"
                  :class="{'icon-disable':data.isDisabled||data.addDisabled}"
                  :disabled="data.isDisabled||data.addDisabled"
                  @click="append(data, node, index, $event)"
                ></Icon>
                <Icon
                  class="icon k-icon-edit"
                  :class="{'icon-disable':data.isDisabled||data.editDisabled}"
                  :disabled="data.isDisabled||data.editDisabled"
                  @click="edit(data, node, index, $event)"
                ></Icon>
                <Icon
                  class="icon k-icon-delete"
                  :class="{'icon-disable':data.isDisabled||data.deleteDisabled}"
                  :disabled="data.isDisabled||data.deleteDisabled"
                  @click="remove(data, node, index, $event)"
                ></Icon>
              </span>
              <Icon
                class="icon k-icon-drag icon-drag"
                :class="{'icon-disable':data.isDisabled||data.dragDisabled}"
                :draggable="!data.isDisabled&&!data.dragDisabled"
                @mousedown="onMousedown(data, node, index, $event)"
                @click="dragClick(data, node, index, $event)"
              ></Icon>
            </span>
          </span>
        </slot>
      </template>
    </Tree>
  </div>
</template>
<script setup>
import {
  nextTick,
  watch,
  reactive,
  ref,
  unref,
  onMounted,
  useAttrs,
  computed,
} from "vue";
import {
  Tree,
  Input,
  Message,
  TreeMode,
  Icon,
  Tooltip,
  Button,
} from "@king-design/vue";
// 输入属性
const props = defineProps({
  checkbox: { type: Boolean, default: false },
  selectable: { type: Boolean, default: true },
  draggable: { type: Boolean, default: true },
  showLine: { type: Boolean, default: false },
  showRootAppend: { type: Boolean, default: false },
  useInnerSearch: { type: Boolean, default: true },
  showSearch: { type: Boolean, default: true },
  expandedKeys: { type: Array, default: [] },
  data: { type: Array, default: [] },
  titleAlign: { type: String, default: 'left' },
});
// 暴露属性
defineExpose({
  get tree() {
    return treeRef.value;
  },
});
// 发射事件
const emit = defineEmits([
  "update:expandedKeys",
  "append",
  "rootAppend",
  "remove",
  "edit",
  "dragend",
  "search",
]);

const localExpandedKeys = ref([...props.expandedKeys]);

const keywordsRef = ref("");
const uniqueId = ref(0);
const treeRef = ref(null);
// tree数据
let dataRef = ref([...props.data]);

// 监听数据变化
watch(
  () => props.expandedKeys,
  (newVal, oldVal) => {
    console.log("watch expandedKeys change", newVal, oldVal);
    localExpandedKeys.value = [...newVal];
  },
  { deep: true }
);

watch(
  () => localExpandedKeys,
  (newVal, oldVal) => {
    console.log("watch localExpandedKeys change", newVal, oldVal);
    emit("update:expandedKeys", newVal);
  },
  { deep: true }
);

watch(
  () => props.data,
  (newVal, oldVal) => {
    // console.log("watch tree数据 change", newVal, oldVal);
    dataRef.value = [...newVal];
  },
  { deep: true }
);
watch(
  () => keywordsRef,
  (newVal, oldVal) => {
    console.log("watch keywordsRef change", newVal, oldVal);
  }
);
const isAllDisabled=(data) => {
  const keys = ['addDisabled', 'editDisabled', 'deleteDisabled']
    return data.isDisabled||keys.every(key => data[key] === true);
}
// 搜索
function filter(data) {
  const keywords = keywordsRef.value;
  if (!keywords) return true;
  return props.useInnerSearch
    ? data.label.toLowerCase().includes(keywords.trim().toLowerCase())
    : true;
}

function itemMousedown(e) {
  console.log("itemMousedown", e);
  if (!e.target.classList.contains("icon-drag")) {
    e?.stopPropagation();
    e.preventDefault();
  }
}

function onMousedown(data, node, index, e) {
  console.log("🚀 ~ onMousedown ~ data, node, index,e:", data, node, index,e)
  if (data.isDisabled || data.dragDisabled) {
    e?.stopPropagation();
    e.preventDefault();
  }
 }

// 如果禁止点击按钮组，那么标题也要禁止点击
function onNodeClick(data, node, index, e) {
  const keys = ['addDisabled', 'editDisabled', 'deleteDisabled']
  if (data.isDisabled || keys.every(key => data[key] === true)) {
    e?.stopPropagation();
    e?.preventDefault();
  }
}

// 控制Tooltip的显示与隐藏
function showTooltip(e, data) {
  // console.log("🚀 ~ showTooltip ~ e.target.clientWidth:", e.target.clientWidth,  "🚀 ~ e.target.scrollWidth:", e.target.scrollWidth, "🚀 ~ e.target.parentElement.clientWidth:", e.target.parentElement.clientWidth);
  // 如果实际内容宽度大于父元素内容宽度，那么显示 tooltip
  if (e.target.scrollWidth>e.target.parentElement.clientWidth-8) {//8是padding
    data.showTooltip=true
  }else{
    data.showTooltip=false
  }
  // console.log("🚀 ~ showTooltip ~ data.showTooltip:", data.showTooltip)
  }


// 拖拽结束
function onDragEnd(...data) {
  console.log("onDragEnd", data);
  emit("dragend", data);
}
// 允许拖拽的条件
function allowDrag(data) {
  console.log("allowDrag", data);
  // return node.key !== "0";
  return true;
}
// 允许插入的条件
function allowDrop(node, srcNode, mode) {
  console.log(
    "allowDrop触发,目标节点：",
    node,
    "目标节点parent：",
    node.parent,
    "源节点：",
    srcNode,
    "源节点parent：",
    srcNode.parent,
    "mode:",
    mode,
    "俩节点parent是否相同：",
    node.parent === srcNode.parent
  );
  // 只能同级节点之间拖动
  if (
    (mode === TreeMode.Before || mode === TreeMode.After) &&
    ((node.parent === null && srcNode.parent === null) ||
      node.parent?.key === srcNode.parent?.key)
  ) {
    return true;
  } else {
    return false;
  }
}
// 拒绝拖拽时处理
function onDenyDrag(node) {
  console.log("onDenyDrag", node);
  // Message.error(`Cannot drag node: ${node.data.label}.`);
}
// 拒绝插入时处理
function onDenyDrop(node) {
  console.log("onDenyDrop", node);
  // Message.error(`Cannot drop to node: ${node.data.label}.`);
}

// 添加节点
function append(data, node, index, e) {
  if (data.isDisabled||data.addDisabled) return;
  console.log("append", data, node, index, e);
  e?.stopPropagation();
  e?.preventDefault();
  emit("append", { data, node, index });
  // const children = data.children || (data.children = []);
  // uniqueId.value++;
  // children.push({
  //   label: "add" + uniqueId.value,
  //   key: uniqueId.value,
  // });
  // dataRef.value = [...dataRef.value];
  // nextTick(() => {
  //   treeRef.value.expand(node.key);
  // });
}
// 删除节点
function remove(data, node, index, e) {
  if (data.isDisabled||data.deleteDisabled) return;
  e?.stopPropagation();
  e?.preventDefault();
  emit("remove", { data, node, index });
  // const children = node.parent ? node.parent.data.children : dataRef.value;
  // children.splice(index, 1);
  // dataRef.value = [...dataRef.value];
}
function dragClick(data, node, index, e) {
  console.log("🚀 ~ dragClick ~ data, node, index, e:", data, node, index, e)
  e?.stopPropagation();
  e?.preventDefault();
}
// 编辑节点
function edit(data, node, index, e) {
  if (data.isDisabled||data.editDisabled) return;
  console.log("edit");
  e?.stopPropagation();
  e?.preventDefault();
  emit("edit", { data, node, index });
}
// 拖拽结束-未触发
function iconDragEnd(data, node, index, e) {
  console.log("iconDragEnd", data, node, index, e);
  e?.stopPropagation();
  e?.preventDefault();
  emit("dragend", { data, node, index });
}
// 往根节点添加节点
function appendToRoot() {
  emit("rootAppend");
  // dataRef.value = [
  //   ...dataRef.value,
  //   {
  //     label: "Appended root node",
  //     key: uniqueId.value++,
  //   },
  // ];
}
// 搜索
function onSearch(value) {
  console.log("onSearch", value);
  emit("search", value);
}
</script>
<style lang="less">
.ks-tree {
  width: 272px;
  padding: 8px 16px 8px 16px;
  border-radius: 4px 0px 0px 4px;
  height: 100%;
  .search {
    width: 100% !important;
    margin-bottom: 8px;
    & .k-input-wrapper {
      &:hover,
      &:active {
        border: 1px solid #1890fe;
        & .k-input-suffix > i:hover {
          color: #1890fe;
        }
      }
    }
  }
  .header {
    display: flex;
    justify-content: space-between;
    padding: 8px 0;
    .header-title {
      font-family: PingFang SC;
      font-size: 14px;
      font-weight: 400;
      color: #151b1e;
    }
    .root-append {
      background-color: #848f9a;
      color: white;
      border-radius: 50%;
      width: 14px;
      height: 14px;
      display: inline-block;
      font-size: 14px;
      line-height: 14px;
      cursor: pointer;
      &:hover {
        background-color: #5fb2ff;
      }
      &:active {
        background-color: #157fe0;
      }
    }
  }
  .tree-box {
    overflow: auto;
    & > .k-tree-node {
      width: 240px;
    }
  }

  .k-tree /deep/ {
    .k-tree-node> .k-tree-label {
      display: flex;
      width: 100%;
      height: 40px;
      line-height: 40px;
      padding: 0 12px;
      border-radius: 4px;
      color: #151b1e;
      &:hover {
        color: #3c4449;
        background-color: #f8fafc !important;
        .icon-operation-group {
          display: inline-flex;
        }
      }
      &.k-tree-leaf{
        padding-left:32px;
      }
      .k-tree-text {
        display: inline-flex;
        flex: 1;
        padding: 0;
        & .tree-content {
          display: inline-flex;
          width: 100%;
          & .text {
            flex: 1;
            padding-right: 8px;
            min-width: 0;
            display: inline-flex;
            align-items: center;
            &:hover {
              color: #1890fe !important;
            }
            .inner-text{
              overflow: hidden;
              text-overflow: ellipsis;
            }
            
          }
          .text-disable,.text-disable:hover{
              cursor:not-allowed;
              color:#B6BEC2!important;
            }
        }
        &:hover {
          background: #f8fafc !important;
        }
      }
      .k-tree-icon {
        display: inline-block;
        margin-right: 12px;
        width: 8px;
        color: #848f9a !important;
        &:hover {
          color: #1890fe !important;
        }
      }

      .icon-operation-group {
        display: none;
        align-items: center;
        .no-drag {
          display: flex;
          align-items: center;
          height: 40px;
        }
        .operate-icons-disabled{
          cursor: not-allowed;
        }
        .icon {
          display: inline-block;
          width: 20px;
          height: 40px;
          padding-right: 4px;
          line-height: 40px;
          &:hover {
            color: #5fb2ff !important;
          }
          &:active {
            color: #157fe0 !important;
          }
          &.icon-disable{
            &:hover{
              color: #bec3c5!important
            }
            &:active {
            color: #bec3c5!important
          }
          }
        }
        .icon-drag{
            padding-right: 0;
          }
          .icon-disable{
           cursor: not-allowed;
           color: #bec3c5!important;
           &:hover{
              color: #bec3c5!important
            }
            &:active {
            color: #bec3c5!important
          }
          }
      }
    }
    .k-tree-node.k-selected > .k-tree-label {
      background-color: #e5f4ff !important;
      color: #1890fe !important;
      & > .k-tree-text {
        background: #e5f4ff !important;
      }
    }
    .k-tree-node {
      min-width: 176px;
      .k-tree-node {
      }
    }
    .k-tree-node > .k-tree {
      margin-left: 0;
      padding-left: 12px;
    }
  }
}
</style>