<template>
  <div class="model-floor-tree scroll-box" :class="{ 'hide-tree': !showTree }">
    <div class="nav-header">
      <span class="title">结构树</span>
      <span class="toolbar">
        <el-icon color="#fff" @click="showTree = !showTree">
          <ArrowUpBold v-if="showTree" />
          <ArrowDownBold v-else />
        </el-icon>
      </span>
    </div>
    <div class="scroll-box model-tree">
      <el-tree :key="treeKey" ref="tree" :props="{
        children: 'children',
        label: 'title',
        isLeaf: 'leaf',
      }" node-key="key" @check="onCheckTree" :load="loadNode" lazy show-checkbox></el-tree>
    </div>
  </div>
</template>

<script>
import { getModelTree, getTreeAllLeafChild } from "@/api/bim/bimModel";
import bimTools from '../bimTools'
export default {
  props: {
    me: {
      type: Object,
      default: () => ({}),
    },
    projectMessage: {
      type: Object,
      default: undefined,
    },
  },
  data() {
    return {
      modelTrees: [],
      replaceFields: {
        title: "name",
        key: "glid",
        value: "glid",
      },
      treeKey: 0,
      expandedKeys: [],
      visibleList: [], //结构树显示构件列表
      checkedKeys: [], //用于清除选中状态
      selectedKeys: [],
      selectedFeature: undefined,
      requestedData: [], //已经请求过得不在请求
      firstClick: true,
      isMobile: false,
      showTree: true,
      visibleList: [],
    };
  },
  mounted() {
    window.mtree = this;
    this.modelTrees = [
      {
        title: "项目模型",
        level: 0,
        type: "root",
        key: "root",
        children: [],
        hadLoad: true,
      },
    ];
    this.projectMessage
      .map((d) => {
        d.gis = JSON.parse(d.gisJson);
        return d;
      })
      .forEach((d) => {
        this.modelTrees[0].children.push({
          title: d.modelName,
          level: 1,
          type: "model",
          hasLoad: false,
          modelId: d.lightweightName,
          key: d.lightweightName,
          externalId: "0",
          glid: "",
          children: [],
          data: d,
        });
      });
    this.expandedKeys = ["root"];
    this.$nextTick(() => { });
  },
  methods: {
    loadNode(node, resolve) {
      let that = this;
      if (node.level == 0) {
        let nd = [
          {
            title: "项目模型",
            level: 0,
            type: "root",
            key: "root",
            children: [],
            hadLoad: true,
          },
        ];

        resolve(nd);
        setTimeout(() => {
          document.querySelectorAll(".model-floor-tree .model-tree .el-tree-node")[0].click();
        }, 1000);
      } else if (node.level == 1) {
        let nd = [];

        that.$parent.models.forEach((d) => {
          let mnd = {
            title: d.modelName,
            level: 1,
            type: "model",
            hasLoad: false,
            modelId: d.lightweightName,
            key: d.lightweightName,
            externalId: "0",
            glid: "",
            children: [],
            data: d,
          };
          nd.push(mnd);
        });
        resolve(nd);
      } else {
        this.getTreeChildren(node, resolve);
      }
    },
    getTreeChildren(node, resolve) {
      let that = this;
      let data = node.data;
      getModelTree(data.modelId, data.glid).then((d) => {
        let tmps = (d.data || []).map((it) => {
          let title = it.externalId == 0 ? it.name : it.externalId;
          title = title.replaceAll('"', "").replaceAll("'", "").replaceAll("\\", "");
          it.title = title;
          it.key = it.glid;
          it.modelId = data.modelId;
          it.type = "data";
          it.leaf = +it.externalId != 0;
          let o = this.convertFeatureInfo(it, data.modelId);
          return o;
        });
        resolve(tmps);
      });
    },
    loadTree(a, b, c) {
      return new Promise((resolve, reject) => {
        if (a.hasLoad) {
          resolve();
          return;
        }
        getModelTree(a.modelId, a.glid).then((d) => {
          (d.data || []).forEach((e) => {
            let title = e.externalId == 0 ? e.name : e.externalId;
            title = title.replace(/[\/\\"]/g, "");
            a.children.push({
              title: title,
              key: e.glid,
              glid: e.glid,
              externalId: e.externalId,
              modelId: a.modelId,
              type: "data",
              featureId: a.modelId + "^" + e.externalId,
              children: [],
              hasLoad: false,
              isLeaf: e.externalId != 0,
              data: e,
            });
          });
          resolve();
        });
      });
    },
    convertFeatureInfo(o, modelId) {
      o.modelId = modelId;
      o.featureId = o.modelId + "^" + o.externalId;
      o.name = o.name || "";
      o.name = o.name.replaceAll('"', "").replaceAll("'", "").replaceAll("\\", "");
      o.info = `[${o.externalId}]${o.groupname}-${o.name}`;
      return o;
    },
     addModel(modelId, cb) {
      bimTools.addModelList(window.api,this.me.bimCfg, this.me.models.filter(m=>m.modelId==modelId), hideParts=>{
        setTimeout(() => {
              bimTools.setDefaultViewPoint(window.api, this.me.bimCfg, this.me.viewPoint)
              bimTools.hideParts(window.api, hideParts);
              cb && cb();
              this.me.resetScene();
              this.$emit("change");
            }, 1000);
      }); 
     },
    onCheckTree(checkNode, event) {
      let checked = event.checkedNodes.includes(checkNode);
      let models = this.$parent.models;
      if (checkNode.type == "root") {
        if (checked) {
          models.forEach((m) => {
            m.visible = true;
            if (api.m_model.has(m.modelId)) {
              api.Model.setVisible(m.modelId, true);
              api.Model.original(m.modelId);
            } else {
              this.addModel(m.modelId);
            }
          });
          this.$emit("change");
        } else {
          models.forEach((m) => {
            api.Model.setVisible(m.modelId, false);
            m.visible = false;
          });
        }
        return;
      }
      if (checkNode.type == "model") {
        let func = () => {
          if (checked) {
            api.Model.setVisible(checkNode.modelId, true);
            api.Model.original(checkNode.modelId);
            this.projectMessage.find((mm) => mm.modelId == checkNode.modelId).visible = true;
            this.$emit("change");
          } else {
            api.Model.setVisible(checkNode.modelId, false);
            this.projectMessage.find((mm) => mm.modelId == checkNode.modelId).visible = false;
            this.$emit("change");
          }
        }
        if (!api.m_model.has(checkNode.modelId)) {
          this.addModel(checkNode.modelId, func);
        } else {
          func();
        }

        return;
      }
      this.showItem(checkNode, event);
    },
    async showItem(checkNode, event) {
      const node = checkNode;
      let checked = event.checkedNodes.includes(checkNode);
      let isPartLoad = false;
      if (!this.projectMessage.find((mm) => mm.modelId == node.modelId).visible && checked) {
        isPartLoad = true;
      }
      let selFeatureIds = [];
      if (node.isLeaf) {
        selFeatureIds.push(node.featureId);
      } else {
        if (!node.leafs) {
          let leafs = await this.getNodeLeafs(node);
          node.leafs = leafs;
        }
        selFeatureIds = node.leafs.map((f) => f.featureId);
      }
      let tmps = selFeatureIds;
      if (!checked) {
        this.setFeatueVisible(tmps, false);
      } else {
        if (isPartLoad) {
          let func = () => {
            api.Model.original(node.modelId);
            let tmpsIds2 = tmps.splice(0, 1000);
            api.Feature.showFeatures(tmpsIds2.join("#"));
            this.setFeatueVisible(tmps, true);
          };
          if (!api.m_model.has(node.modelId)) {
            this.addModel(node.modelId, func);
          } else {
            api.Model.setVisible(node.modelId, true);
            this.$parent.models.find((d) => d.modelId == node.modelId).visible = true;
            api.Model.original(node.modelId);
            func();
          }
        } else {
          this.setFeatueVisible(tmps, true);
        }
      }
    },
    setFeatueVisible(featureIds, show) {
      let len = 1000;
      let cnt = featureIds.length;
      if (cnt == 0) {
        return;
      }
      for (let i = 0; i < cnt; i += len) {
        api.Feature.setVisible(featureIds.slice(i, i + len).join("#"), show);
      }
    },
    async getNodeLeafs(node) {
      const res = await getTreeAllLeafChild(node.modelId, node.glid);
      return (res.data || []).map((o) => {
        o.modelId = node.modelId;
        o.featureId = o.modelId + "^" + o.externalId;
        o.name = o.name || "";
        o.name = o.name.replaceAll('"', "").replaceAll("'", "").replaceAll("\\", "");
        o.info = `[${o.externalId}]${o.groupname}-${o.name}`;
        return o;
      });
    },
  },
};
</script>

<style lang="scss">
.model-floor-tree {
  position: absolute;
  width: 300px;
  top: 20px;
  height: 80vh;
  left: 20px;
  color: #fff;
  background: #274754;

  &.hide-tree {
    height: 50px;

    .ant-tree {
      display: none;
    }
  }

  .nav-header {
    border-bottom: solid 1px #fff;
    line-height: 40px;
    padding: 0px 10px;
    position: relative;

    .title {
      color: rgb(0, 255, 212);
      font-weight: bold;
    }

    .toolbar {
      position: absolute;
      right: 10px;

      .el-icon {
        cursor: pointer;
      }
    }
  }

  .ant-tree {
    background: transparent;
    color: #fff;
  }

  .scroll-box {
    margin-top: 15px;
    height: 64vh;
    overflow-y: auto;

    &::-webkit-scrollbar {
      //整体样式
      height: 8px;
      width: 8px;
    }

    &::-webkit-scrollbar-thumb {
      //滑动滑块条样式
      border-radius: 1px;
      box-shadow: inset 0 0 1px rgba(255, 255, 255, 0.2);
      background: #ffffff;
    }

    &::-webkit-scrollbar-track {
      //轨道的样式
      box-shadow: 0;
      border-radius: 0;
      background: rgba(255, 255, 255, 0.3);
    }

    .ant-tree-node-content-wrapper {
      color: #ffffff;
      white-space: nowrap;

      &.ant-tree-node-selected {
        background: #409eff54 !important;
      }
    }

    .ant-list-empty-text {
      padding: 5px;
      text-align: left;
    }
  }

  .model-tree {
    height: calc(100% - 60px);
    overflow-y: auto;

    .el-tree {
      background: transparent;
      color: #eee;

      .el-checkbox {
        color: #45fdfe;
      }

      .el-tree-node {
        &:focus {
          &>.el-tree-node__content {
            background: #3489d966;

            &:hover {
              background: #3489d966;
            }
          }
        }

        .el-tree-node__content:hover {
          background: #3489d966;
        }
      }
    }
  }
}
</style>
