<template>
  <div class="floating">
    <div>
      <Logo :show-logo="!isCollapse"/>
      <div style="height: 30px; padding: 0 8px 8px 8px" @click="expandMenu" id="tutorial_search_menu">
        <el-input
            ref="searchRef"
            v-model="menuText"
            prefix-icon="Search"
            clearable
            @input="searchInput"
            placeholder="菜单太难找？在这里搜索。"/>
      </div>
    </div>

    <div class="layout_flex_1-y">
      <el-scrollbar>
        <el-menu
            ref="menuRef"
            :collapse-transition="false"
            :collapse="isCollapse"
            :default-active="isSearch ? '' : activeMenu"
            :unique-opened="isSearch ? false : expandOneMenu">
          <template v-for="item in isSearch ? searchData : menuData">
            <menu-item-v2
                :data="item"
                v-if="item?.metaShowMenu"
                :menuText="menuText"/>
          </template>
        </el-menu>
      </el-scrollbar>
    </div>

  </div>
</template>

<script setup lang="ts">
import MenuItemV2 from "./MenuItemV2.vue";
import {computed, nextTick, onMounted, Ref, ref, watch} from "vue";
import {useRoute} from "vue-router";
import Logo from '../HeaderV2/Logo.vue'
import XEUtils from "xe-utils";
import router, {routerMenus} from '@/router'
import sleep from "@/utils/sleep";
import {treeSearch} from "@/utils/array-utils";
import {useCompRef} from "@/utils/useCompRef";
import {ElMenu} from "element-plus";
import {useSystemStore} from "@/pinia/system-store";
import {stringNotBlank} from "@/utils/blank-utils";

const menuText: Ref<string> = ref('')
const menuRef = useCompRef(ElMenu)
const menuData = computed(() => {
  return routerMenus.value
})
const isSearch = ref<boolean>(false)
const searchData = ref([])
const searchActives = new Set()

const searchInput: (val: string) => void = XEUtils.debounce(async (val: string) => {
  menuText.value = val;
  searchActives.clear();

  if (val) {
    searchData.value = treeSearch<{ metaTitle: string; }>(menuData.value, (item) => {
      const metaTitle: string = item.metaTitle
      if (stringNotBlank(metaTitle)) {
        return metaTitle.includes(val);
      }
      return false
    });
    isSearch.value = true
    await nextTick()
    expandNodes(searchData.value)
  } else {
    searchData.value = []
    await nextTick()
    isSearch.value = false
    smoothScrolling()
  }
}, 500)

const expandNodes = (treeData) => {
  const traverse = tempData => {
    XEUtils.arrayEach(tempData, (item) => {
      if (item.children !== null && item.children.length > 0) {
        menuLaunch(item.name)
        traverse(item.children);
      }
    })
  }
  traverse(treeData)
}

const menuLaunch = async path => {
  await nextTick();
  const li = document.getElementById(path);
  const div = li.children[0];
  const icon = div.getElementsByClassName('el-icon el-sub-menu__icon-arrow');
  // @ts-ignore
  if (icon.item(0).style.transform === 'none') {
    try {
      // @ts-ignore
      div!.click();
    } catch (e) {
    }
  }
}

const systemStore = useSystemStore()
const expandOneMenu = computed<boolean>(() => systemStore.expandOneMenu)
const route = useRoute()
const isCollapse = computed<boolean>(() => systemStore.getCollapse)

const expandMenu = () => {
  if (isCollapse.value) {
    systemStore.setCollapse(false)
    setTimeout(() => {
      searchRef.value!.focus()
    }, 100)
  }
}

const searchRef: Ref<HTMLHeadElement | null> = ref(null)

const activeMenu = computed<string>(() => {
  const {meta, path} = route
  if (meta['activeMenu']) {
    return meta['activeMenu'] as string
  }
  return path
})

const smoothScrolling = () => {
  const routerPath = document.getElementById(<string>router.currentRoute.value.name)
  if (!routerPath) return
  routerPath.scrollIntoView({
    block: 'center',
    inline: 'nearest',
    behavior: 'smooth'
  })
}

watch(() => router.currentRoute.value, async () => {
  menuText.value = ''
  isSearch.value = false
  await nextTick()
  await sleep(200)
  smoothScrolling()
})


onMounted(async () => {
  await nextTick()
  await sleep(500)
  smoothScrolling()
})
</script>

<style scoped lang="scss">
.floating {
  height: 100%;
  width: 100%;
  background-color: var(--el-menu-bg-color);
  display: flex;
  flex-direction: column;

  .el-menu {
    border-right: 0 !important;
    position: relative;
  }

  .menu {
    overflow: auto;
  }

}

:deep(.el-sub-menu__title) {
  padding: 0 16px;
}
</style>
