<template>
  <view class="tree-item">
    <view
      class="head"
      @click.stop="changeShow"
			style="padding-left: 10rpx"
      :class="{ active: isItemActive(item) }"
    >
		<!--  -->
      <text class="txt">{{ item[defaultProps.label] }}</text>
      <view
        class="left-icon"
        :class="show ? 'rt45' : ''"
        v-if="hasChildren"
      ></view>
    </view>
    <view class="content" v-if="shouldRecurse">
      <view
        v-for="(node, index) in nodes"
        :key="node._uid"
        class="tree-node-item"
      >
        <view
          class="head"
          @click.stop="toggleNode(index)"
          :style="{ paddingLeft: (node._level + 1) * 10 + 20 + 'rpx' }"
          :class="{ active: isItemActive(node) }"
        >
          <text class="txt">{{ node[defaultProps.label] }}</text>
          <view
            class="left-icon"
            :class="node._isExpanded ? 'rt45' : ''"
            v-if="getNodeChildren(node).length > 0"
          ></view>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  name: "TreeNode",
  componentName: "TreeNode",
  props: {
    item: {
      type: Object,
      default: function () {
        return {};
      },
    },
    defaultProps: {
      type: Object,
      default: function () {
        return {
          id: "id",
          children: "children",
          label: "label",
        };
      },
    },
    selectedNodeId: {
      type: [String, Number],
      default: null,
    },
  },
  computed: {
    hasChildren: function () {
      return (
        this.item[this.defaultProps.children] &&
        this.item[this.defaultProps.children].length > 0
      );
    },
    shouldRecurse: function () {
      return this.hasChildren && this.show;
    },
  },
  data: function () {
    return {
      show: false,
      nodes: [], // 扁平化后的节点列表
    };
  },
  methods: {
    // 判断节点是否被选中
    isItemActive: function (node) {
      if (!this.selectedNodeId || !node) return false;
      return node[this.defaultProps.id] === this.selectedNodeId;
    },

    // 获取节点的子节点
    getNodeChildren: function (node) {
      if (node && node[this.defaultProps.children]) {
        return node[this.defaultProps.children];
      }
      return [];
    },

    // 切换节点展开/折叠状态
    toggleNode: function (index) {
      var node = this.nodes[index];
      if (node) {
        // 触发节点点击事件
        this.$emit("node-click", node);

        // 如果有子节点，切换展开状态
        if (this.getNodeChildren(node).length > 0) {
          // 更新节点状态
          this.$set(node, "_isExpanded", !node._isExpanded);

          // 触发展开/折叠事件
          this.$emit(node._isExpanded ? "node-expand" : "node-collapse", node);

          // 重新构建扁平节点
          this.buildFlatNodes();
        }
      }
    },

    // 根节点的展开/折叠
    changeShow: function () {
      // 触发根节点点击事件
      this.$emit("node-click", this.item);

      if (this.hasChildren) {
        this.show = !this.show;

        // 触发展开/折叠事件
        this.$emit(this.show ? "node-expand" : "node-collapse", this.item);

        // 当展开时，构建扁平节点列表
        if (this.show) {
          this.buildFlatNodes();
        } else {
          this.nodes = [];
        }
      }
    },

    // 构建扁平的节点列表
    buildFlatNodes: function () {
      var result = [];
      var children = this.item[this.defaultProps.children] || [];

      // 添加第一层子节点
      for (var i = 0; i < children.length; i++) {
        var node = children[i];
        if (!node._uid) {
          this.$set(node, "_uid", this.generateUID());
        }
        if (typeof node._level === "undefined") {
          this.$set(node, "_level", 0);
        }
        if (typeof node._isExpanded === "undefined") {
          this.$set(node, "_isExpanded", false);
        }

        result.push(node);

        // 如果节点已展开且有子节点，递归添加子节点
        if (node._isExpanded) {
          this.addChildrenToResult(node, result, 1);
        }
      }

      this.nodes = result;
    },

    // 递归添加子节点到结果数组
    addChildrenToResult: function (parentNode, result, level) {
      var children = this.getNodeChildren(parentNode);

      for (var i = 0; i < children.length; i++) {
        var child = children[i];
        if (!child._uid) {
          this.$set(child, "_uid", this.generateUID());
        }
        this.$set(child, "_level", level);
        if (typeof child._isExpanded === "undefined") {
          this.$set(child, "_isExpanded", false);
        }

        result.push(child);

        // 如果子节点已展开且有子节点，继续递归
        if (child._isExpanded && this.getNodeChildren(child).length > 0) {
          this.addChildrenToResult(child, result, level + 1);
        }
      }
    },

    // 生成唯一ID
    generateUID: function () {
      return (
        Math.random().toString(36).substring(2, 15) +
        Math.random().toString(36).substring(2, 15)
      );
    },
  },
};
</script>

<style scoped lang="scss">
@mixin animate2 {
  -moz-transition: all 0.2s linear;
  -webkit-transition: all 0.2s linear;
  -o-transition: all 0.2s linear;
  -ms-transition: all 0.2s linear;
  transition: all 0.2s linear;
}
.tree-item {
  .head {
    display: flex;
    align-items: center;
    line-height: 60rpx;
    min-height: 60rpx;
    position: relative;
    // padding-right: 50rpx;
    &.active {
      background-color: #fff;
    }
    .txt {
      flex: 1;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      width: 100%;
      height: 84rpx;
      line-height: 84rpx;
      color: #666;
      font-family: "PingFang SC";
      font-size: 28rpx;
      font-weight: 400;
    }
  }
  .left-icon {
    width: 30rpx;
    height: 30rpx;
    flex-shrink: 0;
    position: absolute;
    right: 10rpx;
    top: 50%;
    transform: translateY(-50%) rotate(-90deg);
    -ms-transform: translateY(-50%) rotate(-90deg);
    -moz-transform: translateY(-50%) rotate(-90deg);
    -webkit-transform: translateY(-50%) rotate(-90deg);
    -o-transform: translateY(-50%) rotate(-90deg);
    @include animate2;

    &::before {
      content: "";
      position: absolute;
      top: 50%;
      left: 50%;
      margin-top: -6rpx;
      margin-left: -6rpx;
      width: 0;
      height: 0;
      border-left: 6rpx solid transparent;
      border-right: 6rpx solid transparent;
      border-top: 12rpx solid #999;
    }

    &.rt45 {
      transform: translateY(-50%) rotate(0deg);
      -ms-transform: translateY(-50%) rotate(0deg);
      -moz-transform: translateY(-50%) rotate(0deg);
      -webkit-transform: translateY(-50%) rotate(0deg);
      -o-transform: translateY(-50%) rotate(0deg);
    }
  }
  .content {
    width: 100%;
  }
  .tree-node-item {
    width: 100%;
  }
}
</style>
