<template>
  <div>
    <div class="i-layout-sider-logo" :class="{ 'i-layout-sider-logo-dark': siderTheme === 'dark' }">
      <transition name="fade-quick">
        <i-link to="/home" v-show="!hideLogo">
          <img :src="rootPath + 'images/logo-small.png'" v-if="menuCollapse" />
          <img :src="rootPath + 'images/logo.png'" v-else-if="siderTheme === 'light'" />
          <img :src="rootPath + 'images/logo-dark.png'" v-else />
        </i-link>
      </transition>
    </div>
    <div v-if="!menuCollapse && layout.menuFilter"><Input v-model="menuFilter" prefix="ios-search" placeholder="搜索菜单..." style="margin: 2%; width: 96%" /></div>
    <Menu
      ref="menu"
      class="i-layout-menu-side i-scrollbar-hide"
      :class="{ 'i-layout-menu-side-collapse': menuCollapse }"
      :theme="siderTheme"
      :accordion="menuAccordion"
      :active-name="activePath"
      :open-names="openNames"
      width="auto"
    >
      <template v-for="(item, index) in siderMenuData" :key="index">
        <template v-if="!menuCollapse">
          <i-menu-side-item v-if="item.children == null || !item.children.length" :menu="item" :key="index" />
          <i-menu-side-submenu v-else :menu="item" />
        </template>
        <template v-else>
          <Tooltip
            :content="layout.showI18n ? $t('Permission_' + item.code) : item.title"
            placement="right"
            v-if="item.children == null || !item.children.length"
            :key="index"
            :theme="siderTheme"
          >
            <i-menu-side-item class="i-layout-menu-side-collapse-top-item" :menu="item" hide-title />
          </Tooltip>
          <i-menu-side-collapse v-else :menu="item" top-level />
        </template>
      </template>
    </Menu>
  </div>
</template>
<script>
  import { nextTick } from 'vue';
  import { mapState, mapGetters } from 'vuex';
  import Setting from '../../../setting';

  import iMenuSideItem from './menu-item.vue';
  import iMenuSideSubmenu from './submenu.vue';
  import iMenuSideCollapse from './menu-collapse.vue';
  import mixinPage from '../../../mixins/page';

  // 元素是否在可视区域
  function isElementInViewport(el) {
    let rect = el.getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  }

  export default {
    name: 'iMenuSide',
    mixins: [mixinPage],
    components: { iMenuSideItem, iMenuSideSubmenu, iMenuSideCollapse },
    data() {
      return {
        menuFilter: null
      };
    },
    props: {
      hideLogo: {
        type: Boolean,
        default: false
      }
    },

    computed: {
      ...mapState('admin/layout', ['siderTheme', 'menuAccordion', 'menuCollapse']),
      ...mapState('admin/menu', ['activePath', 'openNames']),
      ...mapGetters('admin/menu', ['filterSider']),
      siderMenuData() {
        if (this.menuFilter) {
          return this.getSiderMenuData(this.copy(this.filterSider));
        } else {
          return this.filterSider;
        }
      }
    },
    watch: {
      $route: {
        handler() {
          this.handleUpdateMenuState();
        },
        immediate: true
      },
      // 在展开/收起侧边菜单栏时，更新一次 menu 的状态
      menuCollapse() {
        this.handleUpdateMenuState();
      }
    },
    methods: {
      handleUpdateMenuState() {
        nextTick(() => {
          if (this.$refs.menu) {
            this.$refs.menu.updateActiveName();
            if (this.menuAccordion) this.$refs.menu.updateOpened();
            // 聚焦当前项
            nextTick(() => {
              const $activeMenu = document.getElementsByClassName('ivu-menu-item ivu-menu-item-active ivu-menu-item-selected');
              if ($activeMenu && $activeMenu.length && !isElementInViewport($activeMenu[0])) {
                const activeMenuTop = $activeMenu[0].getBoundingClientRect().top - Setting.headerHeight;
                const $menu = this.$refs.menu.$el;
                setTimeout(() => {
                  this.$ScrollTop($menu, {
                    to: activeMenuTop,
                    time: 0
                  });
                }, 300);
              }
            });
          }
        });
      },
      isMatch(menu, deep) {
        let name = this.layout.showI18n ? this.$t('Permission_' + menu.code) : menu.title;
        if (name.indexOf(this.menuFilter) >= 0) {
          return true;
        } else {
          if (menu.children && deep) {
            return menu.children.some(item => this.isMatch(item, deep));
          } else {
            return false;
          }
        }
      },
      getSiderMenuData(data) {
        let result = data.filter(item => this.isMatch(item, true));

        for (let menu of result) {
          if (menu.children && !this.isMatch(menu, false)) {
            menu.children = this.getSiderMenuData(menu.children);
          }
        }

        return result;
      }
    }
  };
</script>
