<template>
  <transition
    name="bx-across-slide"
    @enter="enter"
    @before-leave="beforeLeave"
    >
    <div 
      class="bx-profession" 
      v-if="value"
      >
      <div class="bx-container">
        <div 
          class="bx-container-head" 
          ref="bxContainerHead"
          >
          <div class="bx-container-title bx-hairline--bottom">
            <div @click="back">
              <bxs-icon 
                size="24px" 
                color="#ccc" 
                name="arrow-left"
                />
            </div>
            <span class="bx-container-title-center">
              职业类别
            </span>
            <div @click="closeMe">
              <bxs-icon 
                size="24px" 
                color="#ccc" 
                name="close"
                />
            </div>
          </div>
          <div>
            <div 
              @click="searchShow"
              >
              <bxs-search
                placeholder="请输入关键字"
                disabled 
                background="#f2f2f2"
                />
            </div>
          </div>
          <div class="bx-container-selected">
            <div class="bx-container-selected-sel">
              已选：
            </div>
            <div 
              class="bx-container-selected-text" 
              v-if="selected && selected.length"
              >
              {{ selectedStr }}
            </div>
            <div 
              class="bx-container-right" 
              v-if="isLeafLevel && isComplaint"
              >
              类别：{{ professionType }}类（符合投保条件）
            </div>
            <div 
              class="bx-container-err" 
              v-if="isLeafLevel && !isComplaint"
              >
              类别：拒保{{ professionType }}类（不符合投保条件）
            </div>
          </div>
          <ul class="bx-container-menu bx-hairline--bottom">
            <li
              @click="onClickMenu(index)"
              v-for="(menu, index) in menuList"
              class="bx-container-item"
              :class="{'active': (index+1) === menuList.length}"
              :key="'menu'+index"
              >
              {{ menu.des }}
            </li>
          </ul>
        </div>

        <div 
          class="bx-container-list" 
          :style="listStyle"
          >
          <ul v-if="professionObj && professionObj.length > 0">
            <li
              class="bx-container-list-li bx-hairline--bottom"
              :class="{'bx-container-highlight': selected && selected.length && selected[selected.length-1].des === item.des}" 
              v-for="(item, index) in professionObj" 
              :key="index" 
              @click="professionChoose(item)" 
              >
              {{ item.des }}
              <div v-if="!item.code">
                <bxs-icon 
                  size="18px" 
                  color="#ccc" 
                  name="arrow-right"
                  />
              </div>
            </li>
          </ul>
        </div>
      </div>
      
      <transition
        name="bx-across-slide"
        @enter="enterSearchPage"
        >
        <div 
          class="bx-search-container" 
          v-if="isShowSearch"
          >
          <div
            class="bx-search-bar bx-hairline--bottom"
            ref="bxSearchBar"
            >
            <bxs-search
              v-model="searchValue"
              placeholder="请输入关键字"
              show-action
              @search="search"
              @cancel="searchCancel"
              @clear="searchClear"
              />
          </div>
          <div 
            class="bx-search-content" 
            :style="searchListStyle"
            >
            <div 
              class="bx-search-result" 
              v-if="searchs.length > 0"
              >
              <div 
                class="bx-search-item bx-hairline--bottom" 
                v-for="(item, index) in searchs" 
                @click="searchAndChooseItem(item)" 
                :key="index"
                >
                <div class="bx-search-name">
                  {{ item.name }}
                </div>
                <div 
                  class="bx-search-job-type" 
                  :class="{'bx-text-warn': !item.flag}"
                  >
                  {{ item.val }}类
                  {{ item.flag ? '（符合投保条件）' : '（不符合投保条件）' }}
                </div>
              </div>
            </div>
            <div v-else>
              <bxs-default-page
                type="emtpy" 
                :inline="false"
                />
            </div>
          </div>
        </div>
      </transition>
    </div>
  </transition>
</template>
<script>
import Popup from '../mixins/popup/index'
import Search from '../search'
import DefaultPage from '../default-page'
import Icon from '../icon'
import { create } from '../utils'

export default create({
  name: 'profession-list',
  components: {
    [Search.name]: Search,
    [DefaultPage.view.name]: DefaultPage.view,
    [Icon.name]: Icon,
  },
  mixins: [Popup],
  data() {
    return {
      totalLevels: 1, // 判断数据层级，共有几层筛选逻辑，默认1层
      isLeafLevel: false, // 最后一层
      isComplaint: false, // 是否符合
      selected: [], // 历史选择项
      // 当前项信息
      currSelect: {}, // 当前选择项
      professionType: '', // 当前职业类别
      professionObj: null, // 当前项列表值
      // 搜索相关项
      isShowSearch: false, // 搜索开关
      searchValue: '', // 搜索key
      searchs: [], // 搜索数据源
      menuList: [{ des: '一级' }], // tab数据
      digit: [
        '一级',
        '二级',
        '三级',
        '四级',
        '五级',
        '六级',
        '七级',
        '八级',
        '九级',
        '十级',
      ], // 转大写字典
      listStyle: '',
      searchListStyle: '',
    }
  },
  props: {
    // 检索key
    childrenKeyName: {
      type: String,
      default: () => 'children',
    },
    // 职业列表集
    columns: {
      type: Array,
      default: () => [],
    },
    // 初始化值
    initialSelection: {
      type: Object,
      default: () => null,
    },
    // 校验函数
    verifyProfess: {
      type: Function,
      default: () => true,
    },
    // 只读属性
    readonly: {
      type: Boolean,
      default: () => false,
    },
  },
  computed: {
    selectedStr() {
      let str = ''
      if (this.selected && this.selected.length) {
        str = this.selected.reduce(
          (preVal, currVal, idx) =>
            `${preVal}${currVal.des && idx > 0 ? '-' : ''}${currVal.des}`,
          '',
        )
      }
      return str
    },
  },
  methods: {
    // 动态样式计算
    calculateListStyle() {
      if (this.$refs.bxContainerHead)
        this.listStyle = {
          height: `${window.innerHeight -
            this.$refs.bxContainerHead.offsetHeight}px`,
        }
    },
    // 选择层级
    onClickMenu(idx) {
      const vm = this
      if (vm.selected.length > idx) {
        vm.isLeafLevel = false
        vm.isComplaint = false
        if (vm.selected.length !== vm.menuList.length) {
          vm.selected = vm.selected.slice(0, idx + 1 - vm.totalLevels)
        } else {
          vm.selected = vm.selected.slice(0, idx - vm.totalLevels)
        }
        vm.professionObj =
          vm.selected.length > 0
            ? vm.selected[vm.selected.length - 1][vm.childrenKeyName]
            : vm.columns
      }
    },
    // 职业选择功能实现
    professionChoose(val) {
      const vm = this
      vm.currSelect = val
      vm.professionAddSelected(val)
      if (!val.code) {
        vm.professionObj = val[vm.childrenKeyName]
      } else if (vm.verifyProfess(vm.currSelect)) {
        // 最后一级职业-符合条件
        vm.isLeafLevel = true
        vm.isComplaint = true
        vm.professionType = val.val
        if (!vm.readonly) {
          vm.$emit('select', vm.selected[vm.selected.length - 1])
          vm.closeMe()
        }
      } else {
        // 最后一级职业-不符合条件
        vm.isLeafLevel = true
        vm.isComplaint = false
        vm.professionType = val.val
      }
    },
    professionAddSelected(val) {
      const vm = this
      // selected为0，或者 selected最后一项子项不包含当前项
      if (
        !vm.selected.length ||
        (vm.selected.length < vm.totalLevels &&
          vm.selected[vm.selected.length - 1][vm.childrenKeyName].some(
            item => item.des === val.des,
          ))
      ) {
        vm.selected.push(val)
      } else {
        vm.selected.pop()
        vm.selected.push(val)
      }
    },
    back() {
      const vm = this
      vm.isLeafLevel = false
      if (vm.selected && vm.selected.length && vm.selected.length > 0) {
        vm.selected.pop()
        vm.professionObj =
          vm.selected.length > 0
            ? vm.selected[vm.selected.length - 1][vm.childrenKeyName]
            : vm.columns
      } else {
        vm.closeMe()
      }
    },
    closeMe() {
      this.$emit('input', false)
    },
    enter() {
      this.totalLevels = 1
      let targetObj = this.columns
      while (
        targetObj[0] &&
        targetObj[0][this.childrenKeyName] &&
        typeof targetObj[0][this.childrenKeyName] === 'object'
      ) {
        this.totalLevels += 1
        if (targetObj[0] && targetObj[0][this.childrenKeyName]) {
          targetObj = targetObj[0][this.childrenKeyName]
        }
      }
      if (
        this.initialSelection &&
        this.initPreProfession(this.initialSelection)
      ) {
        // 存在默认值
        this.professionObj = this.selected[this.selected.length - 2][
          this.childrenKeyName
        ]
      } else {
        // 初始化
        this.professionObj = this.columns
      }
      this.calculateListStyle()
    },
    beforeLeave() {
      const vm = this
      vm.isLeafLevel = false
      vm.isComplaint = false
      vm.selected = []
      vm.professionType = ''
    },
    // 搜索功能实现
    enterSearchPage() {
      if (!this.searchListStyle && this.$refs.bxSearchBar) {
        this.searchListStyle = {
          height: `${window.innerHeight -
            this.$refs.bxSearchBar.offsetHeight}px`,
        }
      }
    },
    searchShow() {
      this.isShowSearch = true
    },
    search() {
      const vm = this
      vm.searchs = []
      const result = vm.treeTranArray(vm.columns, '', [])
      result.forEach(item => {
        if (item.des.indexOf(vm.searchValue) !== -1) {
          const temp = {}
          const desArr = item.des.split('-')
          temp.des = desArr[desArr.length - 1]
          temp.code = item.code
          temp.val = item.val
          temp.name = item.des
          if (vm.verifyProfess(temp)) {
            temp.flag = 1
          } else {
            temp.flag = 0
          }
          vm.searchs.push(temp)
        }
      })
    },
    searchCancel() {
      this.isShowSearch = false
      this.searchClear()
    },
    searchClear() {
      this.searchs = []
      this.searchValue = ''
    },
    searchAndChooseItem(params) {
      const vm = this
      const temp = params
      if (params.flag) {
        temp.val = parseFloat(params.val)
        vm.$emit('select', temp)
        if (!vm.readonly) {
          vm.closeMe()
          vm.searchCancel()
        } else {
          vm.$toast('符合投保条件')
        }
      } else {
        vm.$toast('该职业不符合投保条件')
      }
    },
    // 数据处理
    initPreProfession(profess) {
      const vm = this
      const result = vm.findProfessionByCode(
        vm.columns,
        profess.code,
        profess.des,
        profess.val,
      )
      vm.selected = result ? result.nodes : []
      if (!vm.selected.length) {
        vm.$toast('暂无该职业或职业类别有误')
        return false
      }
      vm.currSelect = vm.selected[vm.selected.length - 1]
      vm.isLeafLevel = true
      vm.professionType = vm.currSelect.val
      if (vm.verifyProfess(vm.currSelect)) {
        vm.isComplaint = true
      } else {
        vm.isComplaint = false
      }
      return true
    },
    treeTranArray(list, des, params) {
      const vm = this
      const res = params
      for (let index = 0; index < list.length; index += 1) {
        const item = list[index]
        if (item[vm.childrenKeyName]) {
          const tempDes = `${des}-${item.des}`
          vm.treeTranArray(item[vm.childrenKeyName], tempDes, res)
        } else {
          const tempDes = `${des}-${item.des}`
          res.push({ ...item, des: tempDes.slice(1) })
        }
      }
      return res
    },
    findProfessionByCode(list, code, des, val, params) {
      const vm = this
      for (let index = 0; index < list.length; index += 1) {
        const item = list[index]
        let data = JSON.parse(JSON.stringify(params || { nodes: [] }))
        if (
          parseFloat(item.code) === parseFloat(code) &&
          item.des === des &&
          item.val === val
        ) {
          data.nodes.push(item)
          return data
        }
        if (item[vm.childrenKeyName]) {
          data.nodes.push(item)
          const result = vm.findProfessionByCode(
            item[vm.childrenKeyName],
            code,
            des,
            val,
            data,
          )
          if (result) {
            return result
          }
        } else {
          data = null
        }
      }
      return null
    },
  },
  watch: {
    selected(val) {
      this.menuList = JSON.parse(JSON.stringify(val))
      if (this.menuList.length < this.totalLevels) {
        this.menuList.push({
          des: this.digit[this.menuList.length],
        })
      }
      this.calculateListStyle()
    },
  },
})
</script>
<style lang="postcss">
@import './index.css';
</style>
