<template>
  <div ref="root" class="nav-container">
    <div class="nav" @mouseleave="releaseContent">
      <div ref="aside" class="nav-aside" :class="horizontal ? 'hoz' : ''">
        <ul class="aside-wrapper" :class="{ horizontal: horizontal }">
          <li
            v-for="(item, index) in data"
            :key="item[menuKey]"
            class="aside-item"
            :class="{ 'item-active': index === navIndex, hoz: horizontal }"
            :style="{ color: index === navIndex && !horizontal ? bgColor : '' }"
            @mouseenter="changeMenu(index)"
          >
            <p class="main-label" :class="{ hoz: horizontal }">
              {{ item[label] }}
              <i
                :class="
                  horizontal ? 'el-icon-arrow-down' : 'el-icon-arrow-right'
                "
              />
            </p>
            <ul
              v-if="
                !horizontal && item.hotChildren && item.hotChildren.length > 0
              "
              class="hot-children"
              @click="linkIt($event)"
            >
              <li
                v-for="jtem in general(item.hotChildren)"
                :key="jtem[menuKey]"
                :data-href="jtem.href"
                :data-router="jtem.router"
                @mouseleave="removeColor($event, jtem, 1)"
                @mouseenter="addColor($event, jtem)"
              >
                {{ jtem[label] }}
              </li>
            </ul>
          </li>
        </ul>
      </div>
      <div
        v-if="contentVisible"
        ref="content"
        class="nav-content"
        :class="{ 'hoz-content': horizontal }"
      >
        <div class="search">
          <el-input
            slot="reference"
            v-model="keyWord"
            clearable
            prefix-icon="el-icon-search"
            size="medium"
            :placeholder="placeholder"
          />
          <div v-if="keyWord" class="search-content">
            <ul v-if="suggestion.length > 0" @click="linkIt($event)">
              <li
                v-for="(item, index) in suggestion"
                :key="index + item[menuKey]"
                :data-href="item.href"
                :data-router="item.router"
                class="sugg-item"
                @mouseleave="removeColor($event, item)"
                @mouseenter="addColor($event, item)"
              >
                {{ item[label] }}
              </li>
            </ul>
            <p v-if="!suggestion.length && keyWord" class="empty">
              没有匹配到结果，请重新输入
            </p>
          </div>
        </div>
        <div>
          <ul
            v-if="navChild"
            :style="{ height: height }"
            class="content-wrapper"
            @click="linkIt($event)"
          >
            <li v-for="item in navChild" :key="item[menuKey]" class="f-wrapper">
              <div
                :style="{
                  color: bgColor,
                  cursor: item.router || item.href ? 'pointer' : 'auto',
                }"
                :data-href="item.href"
                :data-router="item.router"
                class="f-label"
              >
                {{ item[label] }}
              </div>
              <template v-if="item[children] && item[children].length > 0">
                <div
                  v-for="jtem in item[children]"
                  :key="jtem[menuKey]"
                  :data-href="jtem.href"
                  :data-router="jtem.router"
                  :class="[jtem.href || jtem.router ? '' : 'disabled']"
                  class="s-label"
                  @mouseleave="removeColor($event, jtem)"
                  @mouseenter="addColor($event, jtem)"
                >
                  {{ jtem[label] }}
                </div>
              </template>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { Input } from 'xl-element-ui'

export default {
  components: {
    elInput: Input
  },
  props: {
    horizontal: {
      type: Boolean,
      default: false
    },
    data: {
      type: Array,
      default: () => []
    },
    props: {
      type: Object,
      default: () => ({
        label: 'label',
        children: 'children'
      })
    },
    width: {
      type: String,
      default: ''
    },
    height: {
      type: String,
      default: '300px'
    },
    bgColor: {
      type: String,
      default: '#409eff'
    },
    targetHref: {
      type: String,
      default: '_self'
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    /* eslint-disable */
    menuKey: String
    /* eslint-enable */
  },
  data() {
    return {
      keyWord: '',
      suggestion: [],
      navIndex: null,
      navChild: null,
      unwatchNavIndex: null,
      contentVisible: false
    }
  },
  computed: {
    label() {
      return this.props.label
    },
    children() {
      return this.props.children
    }
  },
  watch: {
    keyWord(v) {
      this.suggestion = []
      this.deepSearch(this.data)
    },
    contentVisible(v) {
      if (v && this.horizontal) {
        this.$nextTick(() => {
          if (this.width) {
            this.$refs.content.style.width = this.width
            return
          }
          this.$refs.content.style.width = this.$refs.aside.clientWidth - 40 + 'px'
        })
      }
    }
  },
  mounted() {
    this.init()
  },
  beforeDestroy() {
    if (this.unwatchNavIndex && typeof this.unwatchNavIndex === 'function') {
      this.unwatchNavIndex()
    }
  },
  methods: {
    removeColor(e, row, flag) {
      if (row.router || row.href) {
        if (flag === 1) {
          e.target.style.color = '#999'
        } else {
          e.target.style.color = '#181818'
        }
      }
    },
    addColor(e, row) {
      if (row.href || row.router) {
        e.target.style.color = this.bgColor
      }
    },
    general(arr) {
      return arr.length > 0 ? arr.length > 3 ? arr.slice(0, 3) : arr : []
    },
    linkIt(e) {
      const { href, router } = e.target.dataset
      if (router) {
        this.routerToItem(router)
        this.contentVisible = false
      } else if (href) {
        this.targetHref === '_self' ? location.href = href : open(href)
      }
    },
    deepSearch(tree) {
      const key = this.keyWord
      if (!key) {
        return
      }
      for (let i = 0, l = tree.length; i < l; i++) {
        const item = tree[i]
        const tag = item[this.label]
        const children = item[this.children]
        if (tag && tag.includes(key) && (item.href || item.router)) {
          this.suggestion.push(item)
        }
        if (children && children.length > 0) {
          this.deepSearch(children)
        }
      }
    },
    releaseContent() {
      this.contentVisible = false
      this.navIndex = null
    },
    changeMenu(idx) {
      this.navIndex = idx
    },
    init() {
      this.unwatchNavIndex = this.$watch('navIndex', (v) => {
        if (v === null) return
        this.navChild = this.data[v][this.children]
        this.contentVisible = true
        this.keyWord = ''
      })
    },
    routerToItem(link, onError) {
      try {
        if (!this.$router) throw new Error('this.$router is undefined')
        this.$router.push({ path: link }, () => { }, onError)
      } catch (e) {
        console.error(e)
      }
    }
  }
}
</script>

<style>
ul,
p,
li {
  list-style: none;
  margin: 0;
  padding: 0;
}
li.aside-item {
  padding: 15px 16px 0;
  font-size: 14px;
  color: #181818;
}
.aside-item.hoz {
  padding: 0 12px;
  color: #fff;
  white-space: nowrap;
}
.aside-item.item-active {
  box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.1);
  transition: box-shadow 0.13s ease-in-out;
  position: relative;
}
.aside-item.item-active::after {
  content: "";
  position: absolute;
  right: 0;
  width: 10px;
  height: 100%;
  background: #fff;
  top: 0;
  z-index: 999;
}
.aside-item.hoz.item-active::after {
  display: none;
}
.aside-item.item-active ul {
  border-bottom: 1px solid #fff;
  transition: all 0.13s ease-in-out;
}
.nav {
  position: relative;
  display: flex;
  font: "Microsoft Yahei", "Hiragino Sans GB", tahoma, arial, "\5B8B\4F53";
}
.nav-aside {
  width: 260px;
  color: #fff;
}
.nav-aside.hoz {
  width: unset;
}
.aside-wrapper {
  background-color: #fff;
}
.aside-wrapper.horizontal {
  display: flex;
  background-color: unset;
}
.hot-children {
  color: #999;
  font-size: 13px;
  display: flex;
  border-bottom: 1px solid #eee;
  margin-top: 6px;
  padding-bottom: 6px;
}
.hot-children li {
  padding-right: 6px;
  margin: 4px 5px 4px 0;
  box-sizing: border-box;
  font-size: 13px;
  color: #999;
  text-decoration: none;
  display: inline-block;
  max-width: 100%;
  border-right: 1px solid #eee;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}
.hot-children li:last-child {
  border: 0;
}
.nav-content {
  flex: 1;
  padding: 20px 20px 0;
  background-color: #fff;
  position: absolute;
  z-index: 99;
  left: 260px;
  width: calc(96% - 260px);
  box-shadow: 0 0 15px 0 rgba(0, 0, 0, 0.1);
  transition: opacity 0.13s ease-in-out, box-shadow 0.13s ease-in-out;
}
.nav-content.hoz-content {
  width: 475px;
  top: 100%;
  left: 0px;
}
.main-label.hoz {
  line-height: 80px;
  cursor: pointer;
  font-size: 15px;
  font-weight: 600;
}
.search {
  position: relative;
}
.search .search-content {
  position: absolute;
  border: 1px solid #ededed;
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
  width: 100%;
  background-color: #fff;
  box-sizing: border-box;
  padding: 12px 0;
}
.nav-container .sugg-item {
  cursor: pointer;
  font-size: 13px;
  line-height: 32px;
  margin: 0 20px;
}
.search .empty {
  color: #999;
  font-size: 15px;
  text-align: center;
  line-height: 50px;
}
.nav-container .content-wrapper {
  margin-top: 20px;
  margin-left: 20px;
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  align-content: flex-start;
  overflow: hidden;
}
.nav-content .el-input--medium .el-input__inner {
  border: none;
  background-color: #f0f0f0;
}
.f-wrapper {
  width: 200px;
  margin-right: 20px;
  margin-bottom: 12px;
}
.f-label {
  display: block;
  font-size: 16px;
  line-height: 32px;
  width: 200px;
  border-bottom: 1px solid #f3f3f5;
}
.s-label {
  font-size: 13px;
  line-height: 32px;
  color: #181818;
  cursor: pointer;
  text-indent: 5px;
}
.s-label.disabled {
  color: #999;
  cursor: auto;
}
</style>
