<template>
  <div
    class="concise-menu"
    ref="conciseMenu"
    :style="menuStyle"
    @mouseenter="handleMouseEnter"
    @mouseleave="handleMouseLeave"
  >
    <div class="menu-search">
      <div class="menu-title">
        <div class="title">功能搜索:</div>
      </div>
      <div class="menu-search-box">
        <i class="iconfont icon-search"></i>
        <input
          type="text"
          class="menu-search-input"
          placeholder="支持拼音首字母搜索"
          v-model.trim="searchWord"
          @focus="handleInputFocus"
          @blur="handleInputBlur"
          @compositionstart="handleCompositionStart"
          @compositionend="handleCompositionEnd"
        />
        <i
          class="el-icon-circle-close"
          style="font-size: 12px; opacity: 0.8; margin-right: 5px"
          v-if="searchWord != ''"
          @click="searchWord = ''"
        ></i>
      </div>
      <div class="menu-search-box">
        <!-- <input type="text" class="menu-search-input" placeholder="支持拼音首字母搜索" v-model.trim="searchWord" /> -->
        <!-- <el-input
          class="menu-search-input"
          clearable
          v-model="searchWord"
          placeholder="支持拼音首字母搜索"
          prefix-icon="el-icon-search"
          @focus.native="handleInputFocus"
          @blur.native="handleInputBlur"
          @compositionstart.native="handleCompositionStart"
          @compositionend.native="handleCompositionEnd"
        ></el-input> -->
        <!-- <i class="iconfont icon-search"></i> -->
      </div>
    </div>
    <div class="menu-content">
      <div class="level1List" v-if="searchWord == ''">
        <!-- 一级菜单列表 -->
        <ul class="area">
          <li v-for="item in menus" :key="item.resId">
            <div class="menu-item">
              <div
                class="level first-level"
                :class="{
                  active: curresId == item.resId,
                  noChild: !item.children || !item.children.length,
                }"
                @click="handleFirstLevelClick(item)"
                @mouseenter="handleFirstLevelMouseEnter(item)"
              >
                <span class="title">{{ item.name }}</span>
                <i
                  v-if="item.children && item.children.length"
                  class="iconfont icon-arrow-right"
                ></i>
              </div>
            </div>
          </li>
        </ul>
        <!-- 二级及以下菜单列表 -->
        <ul class="area child-menu">
          <li v-for="item in childrenData" :key="item.resId">
            <div class="menu-item menu-item2">
              <div>
                <div
                  class="level second-level"
                  :class="{
                    active:
                      curresId == item.parentId &&
                      item.children &&
                      item.children.length,
                    noChild: !item.children || !item.children.length,
                  }"
                  @click="handleSecondLevelClick(item)"
                >
                  <span class="title">{{ item.name }}</span>
                  <!-- <i
                    v-if="item.children && item.children.length"
                    class="iconfont icon-arrow-right"
                  ></i> -->
                </div>
              </div>

              <!-- 三级菜单 -->
              <ul
                class="child-area"
                v-if="item.children && item.children.length"
              >
                <template v-for="child in item.children">
                  <!-- 普通三级菜单项 -->
                  <li
                    :key="child.resId"
                    v-if="
                      child.isShow && !(child.children && child.children.length)
                    "
                  >
                    <div class="menu-item">
                      <div class="third-level" @click="handleOpenFunc(child)">
                        <span class="title">{{ child.name }}</span>
                        <i
                          v-if="child.children && child.children.length"
                          class="iconfont icon-arrow-right"
                        ></i>
                      </div>
                    </div>
                  </li>

                  <!-- 嵌套子菜单组件 -->
                  <nav-sub-menus
                    :level="0"
                    :menuitem="child"
                    :parent="conciseMenu"
                    v-if="
                      child.isShow && child.children && child.children.length
                    "
                    :key="child.resId"
                  >
                  </nav-sub-menus>
                </template>
              </ul>
            </div>
          </li>
        </ul>
      </div>
      <div class="searchResultList" v-else>
        <ul>
          <li
            v-for="(searchItem, index) in searchList"
            :key="'search-' + index"
            :data-index="index"
            :title="searchItem.name"
            @click="handleOpenFunc(searchItem)"
          >
            <itemIcon :item="searchItem"></itemIcon>
            <span>{{ searchItem.name }}</span>
          </li>
          <li v-show="searchList.length == 0">
            {{ $t("hivuiMain_nodata") }}
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
import itemIcon from "@main/views/layout/components/allFuncMenu/itemIcon";
import NavSubMenus from "./menus.vue";
import pinyin from "js-pinyin";
import cloneDeep from "lodash/cloneDeep";
export default {
  name: "ConciseMenu",
  inject: ["addTab"],
  provide() {
    let me = this;
    return {
      hideMenus() {
        me.handleMouseLeave();
      },
    };
  },
  components: { NavSubMenus, itemIcon },
  props: {
    targetElRect: {
      type: Object,
      required: true,
    },
    placement: {
      type: String,
      default: "right",
    },
  },
  data() {
    return {
      searchWord: "",
      searchList: [],

      isVisible: false,
      isMouseOverMenu: false,
      isInputFocus: false,
      isComposing: false,
      curresId: "",
      childrenData: [],
    };
  },
  watch: {
    targetElRect: {
      handler() {
        this.updatePosition();
      },
      deep: true,
    },
    searchWord(newVal, oldVal) {
      this.seldIndex = 0;
      this.doSearch(newVal);
    },
  },
  computed: {
    menuStyle() {
      return {
        position: "absolute",
        top: this.isVisible ? this.position.top + "px" : "-9999px",
        left: this.position.left + "px",
        opacity: this.isVisible ? 1 : 0,
        visibility: this.isVisible ? "visible" : "hidden",
        width: this.isVisible ? "700px" : "0",
        transition: " opacity 0.3s ease 0.1s, visibility 0.3s ease 0.1s",
        backgroundColor: "rgba(255, 255, 255, 1)",
        boxShadow: "0px 0px 6px  rgba(0, 0, 0, 0.25)",
        boxSizing: "border-box",
        overflow: "hidden",
        zIndex: 1000,
      };
    },
    position() {
      return {
        top: 0,
        left: 0,
      };
    },
    menus() {
      const menus = this.$store.getters.menus.filter((item) => item.isShow);
      return menus;
    },
  },
  methods: {
    /**
     * 显示菜单
     */
    show() {
      this.isVisible = true;
      this.$nextTick(() => {
        this.updatePosition();
      });
    },

    /**
     * 隐藏菜单
     */
    hide() {
      if (this.isComposing || this.isInputFocus) {
        return;
      }
      this.isVisible = false;
    },

    /**
     * 更新菜单位置
     */
    updatePosition() {
      if (!this.isVisible) return;

      this.$nextTick(() => {
        const menuEl = this.$el;
        if (!menuEl) return;

        const rect = this.targetElRect;
        if (!rect) return;

        let top = rect.top;
        let left = rect.right;
        if (this.placement != "right") {
          top = top + rect.height;
          left = 0;
        }
        // 应用位置
        menuEl.style.top = top + "px";
        menuEl.style.left = left + "px";
      });
    },

    /**
     * 鼠标进入菜单区域处理
     */
    handleMouseEnter(e) {
      if (e) {
        const target = e.target || e.srcElement;
        if (target.closest && target.closest(".pl-menus-item")) {
          this.isMouseOverMenu = true;
          return;
        }
      }
      this.isMouseOverMenu = true;
    },

    handleInputFocus() {
      this.isInputFocus = true;
    },

    handleInputBlur() {
      this.isInputFocus = false;
    },

    handleCompositionStart() {
      this.isComposing = true;
      console.log("+++++compositionstart", this.isComposing);
    },

    handleCompositionEnd() {
      this.isComposing = false;
      console.log("----compositionend", this.isComposing);
    },

    /**
     * 鼠标离开菜单区域处理
     */
    handleMouseLeave(e) {
      if (e) {
        const relatedTarget = e.relatedTarget || e.toElement;
        if (
          relatedTarget &&
          relatedTarget.closest &&
          relatedTarget.closest(".pl-menus-item")
        ) {
          this.isMouseOverMenu = true;
          return;
        }

        if (!relatedTarget) {
          const activeEl = document.activeElement;
          if (
            this.$el &&
            (this.isComposing ||
              this.isInputFocus ||
              this.$el.contains(activeEl))
          ) {
            this.isMouseOverMenu = true;
            return;
          }
        }
      }
      this.isMouseOverMenu = false;
      this.hide();
    },

    /**
     * 处理一级菜单点击事件
     */
    handleFirstLevelClick(item) {
      if (!item.children || !item.children.length) {
        this.handleOpenFunc(item);
      }
    },

    /**
     * 处理一级菜单鼠标悬停事件
     */
    handleFirstLevelMouseEnter(item) {
      if (item.children && item.children.length) {
        this.handleOpenFunc(item, true);
      }
    },

    /**
     * 处理二级菜单点击事件
     */
    handleSecondLevelClick(item) {
      if (!item.children || !item.children.length) {
        this.handleOpenFunc(item);
      }
    },

    /**
     * 打开功能页面
     * @param {Object} item - 菜单项
     * @param {Boolean} isTabClick - 是否是标签页点击（仅设置子菜单数据）
     */
    async handleOpenFunc(item, isTabClick) {
      let me = this;
      if (isTabClick) {
        this.setChildrenData(item.resId);
        return;
      }

      if (item.type == "link") {
        window.open(item.resUrl, item.name);
        return;
      } else if (item.type == "sso") {
        item.ssoUrl = await me.$store.dispatch("user/openSSOFuncPage", {
          serviceUrl: item.resUrl,
        });
      }

      // 添加标签页
      me.addTab(item);

      setTimeout(() => {
        me.handleMouseLeave && me.handleMouseLeave();
      }, 100);
    },

    /**
     * 设置子菜单数据
     * @param {String} resId - 菜单资源ID
     */
    setChildrenData(resId) {
      this.curresId = resId;
      const menu = this.menus.find((m) => m.resId === resId);
      if (menu && menu.children) {
        this.childrenData = menu.children;
      } else {
        this.childrenData = [];
      }
    },
    //获取搜索列表数据
    doSearch(cnKey) {
      let me = this;
      let list = [],
        records = me.$store.getters.menusList,
        hideMenuItemList = me.$store.getters.hideMenuItemList;
      let py = pinyin.getCamelChars(cnKey).toLocaleLowerCase();
      let re = new RegExp("^[a-zA-Z]+$");
      for (let i = 0, l = records.length; i < l; i++) {
        let item = records[i];
        if (!(!item.isShow || hideMenuItemList.indexOf(item.parentId) != -1)) {
          if (item.parentId == -1 && item.type == "root") {
            continue;
          }
          if (re.test(cnKey)) {
            let y = pinyin.getCamelChars(item.name).toLocaleLowerCase();
            if (y.indexOf(py) > -1 && item.type != "dir") {
              list.push(item);
            }
          } else {
            if (item.name.indexOf(cnKey) > -1 && item.type != "dir") {
              list.push(item);
            }
          }
        }
      }
      me.$set(me, "searchList", list);
      // me.$nextTick(() => {
      //   me.countHeight();
      //   me.$refs.listBox.scrollTo({
      //     top: 0,
      //   });
      // });
    },
  },
  mounted() {
    if (this.menus.length > 0) {
      const menu = this.menus[0];
      this.setChildrenData(menu.resId);
    }
  },
};
</script>

<style lang="less" scoped>
.concise-menu {
  // border-radius: 5px;
  .title {
    font-weight: 400;
  }
  ul,
  li {
    padding: 0;
    margin: 0;
    list-style: none;
  }

  * {
    box-sizing: border-box;
  }
  .menu-search {
    display: flex;
    background-color: rgba(235, 241, 247, 1);
    border-bottom: 1px solid rgba(206, 215, 224, 1);
    height: 48px;
    padding-left: 15px;
    align-items: center;

    .menu-title {
      // width: 110px;
      text-align: right;
      padding-right: 10px;
    }
    .menu-search-box {
      width: 240px;
      display: flex;
      align-items: center;
      background-color: #fff;
      padding-right: 10px;
      border-radius: 5px;
      input {
        flex: 1;
        border: none;
        outline: none;
        line-height: 28px;
        padding: 0 15px;
        padding-left: 0;
        border-radius: 5px;
      }
      i {
        font-size: 20px;
        padding: 0 5px;
        cursor: pointer;
        color: #828282;
      }
    }
  }

  .menu-content {
    position: relative;
    .level1List {
      min-height: 350px;
      max-height: calc(100vh - 200px);
      overflow: auto;
    }
    .area {
      display: flex;
      flex-direction: column;

      li {
        &:first-child {
          .menu-item {
            .first-level {
              border-top: none;
            }
          }
        }
        &:last-child {
          .menu-item2 {
            border-bottom: none;
          }
        }
      }

      &.child-menu {
        width: calc(100% - 168px);
        height: 100%;
        position: absolute;
        top: 0;
        right: 0;
        background-color: #fff;
        overflow: auto;
        padding-left: 24px;
        padding-right: 20px;
        .menu-item2 {
          padding: 12px 0;
          border-bottom: 1px dashed rgba(184, 184, 184, 1);
        }
      }

      .menu-item {
        display: flex;
        flex-direction: column;
        .level {
          position: relative;
          width: 168px;
          text-align: left;
          padding-left: 15px;
          i {
            position: absolute;
            right: 5px;
            top: 50%;
            transform: translateY(-50%);
          }

          &.noChild {
            cursor: pointer;
          }

          &.first-level {
            cursor: pointer;
            background-color: rgba(247, 247, 247, 1);
            // border: 1px solid #ced7e0;
            border-bottom: none;
            line-height: 40px;

            &.active {
              // color: rgba(0, 102, 204, 1);
              background-color: #fff;
              border-right-color: transparent;
              cursor: default;
            }

            &:hover {
              // color: rgba(0, 102, 204, 1);
            }
          }

          &.second-level {
            width: 100%;
            // padding-top: 5px;
            padding-left: 5px;
            // padding-bottom: 5px;

            &.active {
              color: rgba(161, 161, 182, 1);
              background-color: #fff;
              border-color: transparent;
              &:hover {
                color: rgba(161, 161, 182, 1);
              }
            }

            &:hover {
              // color: rgba(0, 102, 204, 1);
            }
          }
        }
      }

      .child-area {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
        padding-top: 3px;
        // gap: 8px;
        // border-bottom: 1px solid #ced7e0;
        li {
          width: 33%;
          // margin-bottom: 12px;
          padding: 5px 6px;
          color: rgba(51, 51, 51, 1);
        }

        .third-level {
          // padding: 0 8px;
          // padding-left: 0;
          // border-left: 1px solid #ced7e0;
          cursor: pointer;

          &:hover {
            // color: rgba(0, 102, 204, 1);
          }
        }

        ::v-deep .pl-menus-item {
          // padding: 0 8px;
          // padding-left: 0;
          // border-left: 1px solid #ced7e0;

          &.pl-menus-itemSeld {
            color: rgba(0, 102, 204, 1);
          }

          .title {
            position: relative;
            font-weight: 400;
            color: #333333;
            .txt {
              display: inline-block;

              i {
                position: initial;
                transform: rotate(90deg);
                // right: -5px;
                // top: 50%;
                // transform: translateY(-50%);
              }
            }
          }
        }
      }
    }

    .searchResultList {
      width: 100%;
      min-height: 100px;
      max-height: calc(100vh - 200px);
      overflow: auto;
      padding: 5px 10px;
      ul {
        display: flex;
        flex-wrap: wrap;
        padding-bottom: 10px;
        li {
          flex: 0 0 33.3%;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
          line-height: 32px;
          font-size: 14px;
          display: flex;
          align-items: center;
          cursor: pointer;
          &:hover {
            // color: #06c;
          }
        }
        .itemSeld {
          // color: #f00;
        }
      }
    }
  }
}
</style>