<template>
  <div :class="['mc-cascader', {'active': visible}]"
       @click="menuClickHandler($event)"
       @mouseover="mouseOverHandler"
       @mouseout="mouseOutHandler"
       v-clickoutside="awayHandler">
    <i class="mc-icon-close close" v-if="showClear && !valueEmpty" @click.stop="clearHandler"></i>
    <input type="text" :title="selectedText" readonly="readonly" placeholder="请选择" :class="['mc-cascader_inner', {'hint': valueEmpty}]" class="mc-select_inner" :value="selectedText">
    <transition name="slideDown">
    <!-- <div v-show="visible" class="mc-cascader_box" :style="{width: `${(menuWidth + 2) * groups.length + 17 * groups.length}px`}" @click.stop="" @mouseover.stop="" @mouseout.stop=""> -->
      <div v-show="visible" class="mc-cascader_box" :style="{width: `${(menuWidth) * groups.length}px`}" @click.stop="" @mouseover.stop="" @mouseout.stop="">
      <ul class="mc-cascader_menu" v-for="(group, groupIndex) in groups" :style="{width: `${menuWidth}px`}">
        <li :class="['item', {'active': selectedItems[groupIndex] && selectedItems[groupIndex][0] === item[0], 'submenu': itemChildren(item).length > 0}]"
            v-for="(item, index) in group" @click.stop="itemClickHandler(item, groupIndex)" :key="item[0]" >
          {{ item[1] }}
        </li>
      </ul>
    </div>
    </transition>
  </div>
</template>
<script>
import clickoutside from '../../assets/js/clickoutside.js'
  import { notify } from '../../assets/js/notify.js'
  export default {
    directives: { clickoutside },
    props: {
      value: Array,
      textDelimiter: { type: String, default: ' / ' },
      menuWidth: { type: Number, default: 160 },
      // hint: { type: String, default: 'Please select' },
      options: { type: Array, required: true } // [[key, label, children]]
    },
    data () {
      return {
        showClear: false,
        visible: false,
        groups: [this.options],
        selectedItems: [],
        selectedText: ''
      }
    },
    mounted () {
      this.selectedItems = this.parseSelectedItems()
      this.selectedText = this.selectedItems.map((ele) => ele[1]).join(this.textDelimiter)
    },
    computed: {
      valueEmpty () {
        return this.value.length === 0
      }
    },
    methods: {
      clearHandler () {
        this.selectedText = null
        this.selectedItems = []
        this.groups = [this.options]
        this.emitChange([])
      },
      mouseOverHandler () {
        this.showClear = true
      },
      mouseOutHandler () {
        this.showClear = false
      },
      menuClickHandler (evt) {
        this.visible = !this.visible
      },
      awayHandler () {
        this.visible = false
      },
      itemClickHandler (item, groupIndex) {
        let children = this.itemChildren(item)
        let howMany = this.selectedItems.length - groupIndex
        this.selectedItems.splice(groupIndex, howMany, item)
        // console.log('after:', this.selectedItems)
        if (children.length > 0) {
          let groupHowMany = this.groups.length - groupIndex
          this.groups.splice(groupIndex + 1, groupHowMany, children)
        } else {
          this.awayHandler()
          this.selectedText = this.selectedItems.map((ele) => ele[1]).join(this.textDelimiter)
          this.emitChange(this.selectedItems.map((ele) => ele[0]))
        }
      },
      emitChange (values) {
        this.$emit('input', values)
        this.$emit('change', values)
        notify.field.change(this)
      },
      itemChildren (item) {
        if (item.length > 2) {
          return item[item.length - 1]
        }
        return []
      },
      parseSelectedItems () {
        // console.log('>>>>:', this.value)
        let ret = []
        if (this.valueEmpty) return ret
        let os = this.options
        let vIndex = 0
        while (os && os.length > 0) {
          for (let ele in os) {
            if (this.value[vIndex] === ele[0]) {
              ret.push(ele)
              os = this.itemChildren(ele)
              break
            }
          }
          vIndex++
          if (vIndex > 10) return []
        }
        return ret
      }
    }
  }
</script>