<template>
  <div class="project-side-menu-container">
    <el-menu mode="vertical" class="project-side-menu-instance" :unique-opened="uniqueOpened" :default-active="defaultActive" @select="menuSelect"
      @open="subMenuOpen" @close="subMenuClose">
      <template v-for="(item,index) of tempMenuTree">
        <project-menu-item :menuItem="item" :key="item.nodeValue">
          <template :slot="`${item.nodeName}-${item.level}`" slot-scope="scope">
            <slot :name="`${scope.data.nodeName}-${scope.data.level}`" :data="scope.data"></slot>
          </template>
        </project-menu-item>
      </template>
    </el-menu>
  </div>
</template>
<script>
import ProjectMenuItem from "@/views/projectCostLedger/detail/components/ProjectSideMenu/ProjectMenuItem";
import { addTreeLevel, addNodeParent } from "@/utils";
export default {
  name: "projectSideMenu",
  components: {
    ProjectMenuItem
  },
  props: {
    // 菜单树形结构对象
    menuTree: {
      type: Array,
      required: false,
      default: () => ([])
    },
    menuOptions: {
      type: Object,
      default: () => ({
        nodeName: "nodeName",
        nodeValue: "id",
        children: "children",
        icon: "icon",
        suffixIcon: "suffixIcon"
      })
    },
    // 只保持打开一个菜单
    uniqueOpened: {
      type: Boolean,
      default: false
    },
    // 默认打开的菜单
    defaultActive: {
      type: String,
      default: ""
    }
  },
  watch: {
    menuTree: {
      handler(newValue) {
        this.comMenuTree = newValue ? newValue : [];
        this.initMenuTree(this.comMenuTree);
      },
      deep: true,
      immediate: true
    }
  },
  data() {
    return {
      defaultMenuOptions: {
        nodeName: "nodeName",
        nodeValue: "id",
        children: "children",
        icon: "icon",
        suffixIcon: "suffixIcon"
      },
      tempMenuOptions: {},
      tempMenuTree: [],
      comMenuTree: this.menuTree
    };
  },
  //可访问data属性
  created() {

  },
  //计算集
  computed: {
    allDisabled() {
      return (!this.menuTree || this.menuTree?.length) ? true : false;
    }
  },
  //方法集
  methods: {
    // 事件订阅
    subMenuOpen(menuPath) {
      this.$emit("open", menuPath);
    },
    subMenuClose(menuPath) {
      this.$emit("close", menuPath);
    },
    menuSelect(menuPath) {
      const result = this.getCurrentData(menuPath);
      this.$emit("select", menuPath, result);
    },
    getCurrentData(only) {
      const _tempTree = JSON.parse(JSON.stringify(this.tempMenuTree));
      if (_tempTree) {
        function findNode(tree = [], target) {
          if (tree instanceof Array) {
            for (const item of tree) {
              if (item.nodeValue === target) return item;
              if (item.children instanceof Array && item.children.length) {
                const _temp = findNode(item.children, target);
                if (_temp) return _temp;
              }
            }
          }
        }
        const result = findNode(_tempTree, only);
        return result;
      }
      return null;
    },
    // 初始化树形结构
    initMenuTree(array = []) {
      if (array?.length) {
        // 合并默认配置 
        const _options = this.mergeMenuOptions(JSON.parse(JSON.stringify(this.menuOptions)));
        this.tempMenuOptions = _options;
        // 映射配置
        const resultData = this.mapDataByMenuOptions(JSON.parse(JSON.stringify(this.comMenuTree)), _options);
        if (resultData) {
          this.tempMenuTree = resultData;
        }
      }
    },
    mergeMenuOptions(options) {
      // 默认配置
      const defaultOptions = JSON.parse(JSON.stringify(this.defaultMenuOptions));
      // 合并配置
      options = options && Object.prototype.toString.call(options) == "[object Object]" ? { ...defaultOptions, ...options } : { ...defaultOptions };

      return options;
    },
    mapDataByMenuOptions(menuList, options) {
      // 分组源数据
      const _groupData = this.groupData(menuList, options);
      // 映射过后的树
      const _mapedData = this.mapData(JSON.parse(JSON.stringify(_groupData)), options);
      // 处理层级 以及删除空children
      return this.buildTree(_mapedData);
    },
    groupData(data, options, originData = []) {
      if (data?.length) {
        const { children } = options;
        const len = data.length;
        for (let index = 0; index < len; index++) {
          const _item = data[index];
          const _newItem = JSON.parse(JSON.stringify(_item));
          originData.push({
            originData: _newItem
          });
          if (_item[children] instanceof Array && _item[children].length) {
            _newItem[children] = this.groupData(_item[children], options);
          } else {
            delete _newItem[children];
          }
        }
      }
      return originData;
    },
    mapData(data = [], mapOptions) {
      const keys = Object.keys(mapOptions);
      if (data?.length) {
        data.forEach(item => {
          // 循环key映射到 树
          keys.forEach(key => {
            const _mapKey = mapOptions[key];
            const _origin = item["originData"];
            if (Object.hasOwnProperty.call(_origin, _mapKey)) {
              item[key] = JSON.parse(JSON.stringify(_origin[_mapKey]));
            }
          });
          if (item?.children instanceof Array && item.children.length) {
            // 递归映射
            this.mapData(item?.children, mapOptions);
          }
        });
      }
      return data;
    },
    buildTree(mapedData) {
      if (mapedData?.length) {
        // 添加层级
        const levelResult = addTreeLevel(mapedData);
        const parentResult = addNodeParent(levelResult);
        return parentResult;
      }
    }
  },
}
</script>
<style lang="scss" scoped>
.project-side-menu-container {
  position: relative;
  width: 100%;
  height: 100%;

  ::v-deep .project-side-menu-instance {
    width: 100%;
    height: 100%;
    border-right: 1px solid #eeeeee;
    overflow: auto;

    /* 重置一级二级菜单 高度行高 */
    .project-menu-item-container {
      /* 有下级菜单 */
      .project-sub-menu-item {
        & > .el-submenu__title {
          height: 32px;
          line-height: unset;
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding-right: 12px;
          padding-left: 0px !important;

          .project-sub-menu-title {
            display: flex;
            align-items: center;
            width: calc(100% - 12px);
            height: 100%;
            color: #232323;
            font-size: 13px;
            font-weight: 350;

            .project-sub-menu-title-text {
              overflow: hidden;
              white-space: nowrap;
              text-overflow: ellipsis;
            }

            & > img {
              width: 16px;
              height: 16px;
              margin-right: 4px;
            }
          }

          .el-submenu__icon-arrow {
            right: 12px;
            font-size: 12px;
            position: static;
            margin-top: 0px;
            width: 12px;
            min-width: 12px;
          }

          &:hover {
            background-color: unset;
            background: linear-gradient(
              91deg,
              rgba(0, 129, 255, 0.1) 0%,
              rgba(0, 129, 255, 0) 100%
            );
          }
        }
      }
      /* 无下级菜单 */
      .project-only-menu-item {
        height: unset;
        line-height: unset;
        font-size: unset;
        padding: 0px !important;
        color: unset;
        cursor: unset;
        position: unset;
        white-space: unset;

        /* 选中 */
        &.is-active {
          .project-only-menu-title-container {
            background-color: unset;
            background: linear-gradient(
              91deg,
              rgba(0, 129, 255, 0.1) 0%,
              rgba(0, 129, 255, 0) 100%
            );
            .project-only-menu-title {
              color: #0081ff;
            }
          }
        }
        .project-only-menu-title-container {
          height: 32px;
          line-height: unset;
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding-right: 12px;
          padding-left: 0px !important;

          &:hover {
            background-color: unset;
            background: linear-gradient(
              91deg,
              rgba(0, 129, 255, 0.1) 0%,
              rgba(0, 129, 255, 0) 100%
            );
          }

          .project-only-menu-title {
            display: flex;
            align-items: center;
            width: 100%;
            height: 100%;
            color: #232323;
            font-size: 13px;
            font-weight: 350;
            cursor: pointer;

            .project-only-menu-title-text {
              overflow: hidden;
              white-space: nowrap;
              text-overflow: ellipsis;
            }

            & > img {
              width: 16px;
              height: 16px;
              margin-right: 4px;
            }
          }
        }
      }
    }
  }
}
</style>
