<template>
  <div class="project-side-menu-container">
    <transition name="fade" :appear="true" mode="out-in">
      <el-menu v-if="tempMenuTree.length" mode="vertical" class="project-side-menu-instance" :unique-opened="uniqueOpened"
        :default-active="createMenuIndex(comDefaultActive)" :default-openeds="comDefaultOpeneds" @select="menuSelect" @open="subMenuOpen"
        @close="subMenuClose" ref="customElMenu">
        <template v-for="(item, index) of tempMenuTree">
          <project-menu-item :menuItem="item" :key="`${item.nodeValue}-${item.level}`">
            <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>
    </transition>
  </div>
</template>
<script>
import ProjectMenuItem from "@/views/projectCostLedger/detail/components/ProjectSideMenu/ProjectMenuItem";
import { addTreeLevel, addNodeParent } from "@/utils";
export default {
  name: "projectSideMenu",
  components: {
    ProjectMenuItem
  },
  model: {
    prop: "defaultActive",
    event: "update:defaultActive"
  },
  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, Number],
      default: ""
    },
    // 默认展开的二级菜单
    defaultOpeneds: {
      type: Array,
      default: () => []
    }
  },
  watch: {
    menuTree: {
      handler(newValue) {
        this.comMenuTree = newValue ? newValue : [];
        this.initMenuTree(this.comMenuTree);
      },
      deep: true,
      immediate: true
    },
    defaultActive: {
      handler(newValue) {
        this.comDefaultActive = newValue;
      }
    },
    defaultOpeneds: {
      handler(newValue) {
        this.comDefaultOpeneds = newValue ? newValue : [];
      }
    }
  },
  data() {
    return {
      defaultMenuOptions: {
        nodeName: "nodeName",
        nodeValue: "id",
        children: "children",
        icon: "icon",
        suffixIcon: "suffixIcon"
      },
      tempMenuOptions: {},
      tempMenuTree: [],
      comMenuTree: this.menuTree,
      comDefaultActive: this.defaultActive,
      comDefaultOpeneds: this.defaultOpeneds
    };
  },
  //可访问data属性
  created() {
    this.openTargetAllSubMenu(this.comDefaultOpeneds);
  },
  //计算集
  computed: {
    allDisabled() {
      return (!this.menuTree || this.menuTree?.length) ? true : false;
    }
  },
  //方法集
  methods: {
    // 获取第一层最深层的id
    getFirstLevelWithDeepId() {
      function getCurrentId(array) {
        const len = array.length;
        for (let index = 0; index < len; index++) {
          if (index > 0) break;
          const item = array[index];
          if (!item?.children) return item.nodeValue;
          return getCurrentId(item.children);
        }
      }
      return getCurrentId(this.tempMenuTree);
    },
    // 获取最终菜单结构
    getResultMenuList() {
      return this.tempMenuTree;
    },
    // 展开所有指定层级的菜单 默认二级
    openTargetAllSubMenu(openeds = [], level = 2) {
      // 组件外传入了值 使用传入值，否则默认获取二级菜单打开二级
      if (openeds instanceof Array && openeds.length) {
        // 转换为字符串
        this.comDefaultOpeneds = openeds.map(item => this.createMenuIndex(item));
      } else {
        // 递归查找当前二级目录index
        const _tempTree = this.tempMenuTree;
        const result = this.findTargetLevelIndex(_tempTree, 2, []);
        // this.comDefaultOpeneds = result;
      }
    },
    findTargetLevelIndex(data = [], level = level, result = []) {
      if (data.length) {
        for (const item of data) {
          // level大于传入level直接跳出循环
          if (item.level > level) break;
          // 确保打开菜单为目录
          if (item.level <= level && item.children instanceof Array) {
            result.push(item.nodeValue);
          }
          if (item.children instanceof Array && item.children.length) {
            this.findTargetLevelIndex(item.children, level, result);
          }
        }
      }
      return result.map(item => this.createMenuIndex(item));
    },
    // 事件订阅
    subMenuOpen(menuPath, menuPathArray) {
      this.$emit("open", menuPath, menuPathArray);
    },
    subMenuClose(menuPath, menuPathArray) {
      this.$emit("close", menuPath, menuPathArray);
    },
    menuSelect(menuPath) {
      this.$emit("update:defaultActive", menuPath);
      if (this.comDefaultActive == menuPath) return;
      const result = this.getCurrentData(menuPath);
      this.$emit("select", menuPath, result);
    },
    createMenuIndex(index) {
      if (index || index == "0") {
        return index.toString();
      }
    },
    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;
    },
    // 初始化树形结构
    async 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;
          await this.$nextTick();
          this.openTargetAllSubMenu(this.comDefaultOpeneds);
        }
      } else {
        this.tempMenuTree = [];
        this.tempMenuOptions = this.$options.data.call(this).tempMenuOptions;
      }
    },
    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);
        console.log(parentResult);
        return parentResult;
      }
    }
  },
};
</script>
<style lang="scss" scoped>
.project-side-menu-container {
  position: relative;
  width: 100%;
  height: 100%;
  border-right: 1px solid #eeeeee;
  background: #fff;
  overflow: auto;

  ::v-deep .project-side-menu-instance {
    width: 100%;
    border-right: unset;
    background: unset;

    /* 重置一级二级菜单 高度行高 */
    .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,
        &:hover {
          /* 重置li默认样式 */
          background-color: 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;
            }
          }
        }

        /* 禁用状态不触发 焦点 */
        &.is-disabled {
          &:focus {
            color: unset !important;
          }
        }

        .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>
