<template>
  <div class="app-container">
    <el-container>
      <el-aside v-loading="loading" :visible.sync="loading">
        <el-input placeholder="输入关键字进行过滤" v-model="filterText" size="small" style="margin-bottom: 10px" clearable/>
        <el-tree class="filter-tree" :data="groupList" @node-click="nodeClick" node-key="id" highlight-current :expand-on-click-node="false" :filter-node-method="filterNode" ref="tree" :default-expanded-keys="[0]">
          <span class="custom-tree-node" slot-scope="{ node, data }" v-if="groupState !== 'list' && editId === data.id">
            <span>
              <el-form ref="form" :model="form" :rules="rules">
                <el-input v-model="form.name" placeholder="请输入节点名称" class="custom-tree-node-input"/>
              </el-form>
            </span>
            <span>
              <el-button type="text" size="mini"><i class="el-icon-check" @click="submitNode(node)"/></el-button>
              <el-button type="text" size="mini"><i class="el-icon-close" @click="cancelNode(node)"/></el-button>
            </span>
          </span>
          <span class="custom-tree-node" slot-scope="{ node, data }" v-else>
            <span @click="nodeSelected(data)" style="width: 100%;">{{ node.label }}</span>
            <span v-if="data.id === 0">
              <el-button type="text" size="mini" @click="nodeAdd(node)"><i class="el-icon-plus"/></el-button>
            </span>
            <span class="custom-tree-node-option" v-else>
              <el-button type="text" size="mini" @click="nodeAdd(node)"><i class="el-icon-plus"/></el-button>
              <el-button type="text" size="mini"><i class="el-icon-edit" @click="nodeEdit(node)"/></el-button>
              <el-button type="text" size="mini"><i class="el-icon-delete" @click="nodeDelete(node)"/></el-button>
            </span>
          </span>
        </el-tree>
      </el-aside>
      <el-main>
        <slot/>
      </el-main>
    </el-container>
  </div>
</template>

<script>
import {addGroup, delGroup, listGroup, updateGroup} from "@/api/test/group";

export default {
  name: "FolderPage",
  props: {
    type: {
      type: String,
      required: true,
      validator: function (value) {
        return ['api', 'task', 'case'].includes(value)
      }
    }
  },
  data() {
    return {
      loading: true,
      filterText: "",
      groupList: [],
      groupState: "list",
      editId: null,
      groupId: null,
      form: {
        name: null
      },
      rules: {
        name: [
          {required: true, message: "节点名不能为空", trigger: "blur"}
        ],
      },
    };
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
  },
  created() {
    this.getGroup();
  },
  methods: {
    getGroup(openList) {
      this.loading = true;
      this.groupList = [{
        id: 0,
        label: "",
        children: []
      }]
      switch (this.type) {
        case "api":
          this.groupList[0].label = "接口管理";
          break;
        case "task":
          this.groupList[0].label = "自动化测试管理";
          break;
        case "case":
          this.groupList[0].label = "用例管理";
          break;
      }
      listGroup(this.type).then(res => {
        res.data.filter(item => item.parentId === 0).map(item => {
          this.groupList[0].children.push({
            id: item.id,
            label: item.name,
            children: this.getChild(res.data, item.id)
          })
        });
        if (res.data && res.data.length > 0) {
          this.groupId = res.data[0].id;
          this.$nextTick(() => {
            this.$refs.tree.setCurrentKey(this.groupId);
            if (openList){
              openList.forEach(item => {
                this.$refs.tree.store.nodesMap[item].expanded = true;
              })
            } else {
              this.$emit('click', this.groupId);
            }
          })
        }
        this.loading = false;
      })
    },
    getChild(data, parentId) {
      return data.filter(item => item.parentId === parentId).map(item => {
        return {
          id: item.id,
          label: item.name,
          children: this.getChild(data, item.id)
        }
      });
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    nodeClick() {
      this.$refs.tree.setCurrentKey(this.groupId);
    },
    nodeSelected(data) {
      if (data.id > 0 && this.groupId !== data.id) {
        this.groupId = data.id;
        this.$emit('click', data.id);
      } else {
        this.$refs.tree.setCurrentKey(this.groupId);
      }
    },
    nodeAdd(node) {
      this.groupState = "add";
      const newChild = {id: -1, label: '', children: []};
      if (!node.data.children) {
        this.$set(node.data, 'children', []);
      }
      node.data.children.push(newChild);
      this.$refs.tree.store.nodesMap[node.data.id].expanded = true;
      this.editId = -1;
    },
    nodeEdit(node) {
      this.groupState = "edit";
      this.editId = node.data.id;
      this.form.name = node.label;
    },
    nodeDelete(node) {
      this.$refs.tree.setCurrentKey(this.groupId);
      this.$modal.confirm('是否确认删除？会连带删除文件夹下所有内容').then(() => {
        return delGroup(node.data.id, this.type);
      }).then(() => {
        this.$modal.msgSuccess("删除成功");
        if (this.groupId === node.data.id) {
          this.$emit("click", null);
        }
        this.$refs.tree.remove(node)
      })
    },
    submitNode(node) {
      this.$refs["form"].validate(valid => {
        if (!valid) return
        if (node.data.id === -1) {
          addGroup({
            parentId: node.parent.data.id,
            type: this.type,
            name: this.form.name,
          }).then(res => {
            this.$modal.msgSuccess("新增成功");
            this.cancelNode();
            let openList = [];
            Object.entries(this.$refs.tree.store.nodesMap).forEach(([key, node]) => {
              if (node.expanded) {
                openList.push(key);
              }
            });
            this.getGroup(openList);
          });
        } else {
          updateGroup({
            id: node.data.id,
            name: this.form.name,
          }).then(res => {
            this.$modal.msgSuccess("修改成功");
            node.data.label = this.form.name;
            this.cancelNode();
          });
        }
      });
    },
    cancelNode(node) {
      if (node && node.data.id === -1) {
        this.$refs.tree.remove(node);
      }
      this.groupState = "list";
      this.editId = null;
      this.form = {
        name: null,
      };
      this.resetForm("form");
    },
  }
};
</script>

<style scoped lang="scss">
.el-aside {
  padding: 20px 0 0;
}

.custom-tree-node-input {
  ::v-deep .el-input__inner {
    height: 24px;
    line-height: 24px;
    font-size: 12px;
  }
}

.el-container {
  height: calc(100vh - 124px);
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}

.el-tree-node__content {
  .custom-tree-node-option {
    display: none;
  }

  &:hover {
    .custom-tree-node-option {
      display: unset;
    }
  }
}
</style>
