<template>
  <div id="userSelect" class="ta-user-select">
    <div v-if="withTag" class="ta-user-select-with-tag">
      <template v-for="item in getUserListById">
        <ta-tooltip v-if="item[defaultProps.listTitle].length > 20" :key="item[defaultProps.listKey]" :title="item[defaultProps.listTitle]">
          <ta-tag :key="item[defaultProps.listKey]" closable :after-close="() => deleteOneUser(item)">
            {{ `${item[defaultProps.listTitle].slice(0, 20)}...` }}
          </ta-tag>
        </ta-tooltip>
        <ta-tag v-else :key="item[defaultProps.listKey]" closable :after-close="() => deleteOneUser(item)">
          {{ item[defaultProps.listTitle] }}
        </ta-tag>
      </template>
      <ta-select v-show="tagSelectVisible" v-model="selectOption" auto-focus :mode="isMulti? 'multiple':'default'" :filter-option="filterOption" style="width: 200px" :not-found-content="fetching ? undefined : '暂无数据'" @search="selectSearch" @deselect="fnDeselect" @select="fnSelect" @blur="tagSelectVisible = false">
        <ta-spin v-if="fetching" slot="notFoundContent" size="small" />
        <ta-select-option v-for="item in userSelectData" :key="item[defaultProps.listKey].toString()" @click="tempItem = item">
          {{ item[defaultProps.listTitle] }}
        </ta-select-option>
      </ta-select>
      <ta-button v-if="!tagSelectVisible" type="dashed" icon="plus" @click="tagSelectVisible = true">
        添加用户
      </ta-button>
      <ta-button icon="user-add" @click="modalShow = true">
        精准选择
      </ta-button>
    </div>
    <ta-modal v-model="modalShowFlag" wrap-class-name="ta-user-select-modal" :title="title" :centered="true" :width="width" :body-style="{'height': '500px', 'padding':'0px', 'overflow': 'hidden'}" :destroy-on-close="true" :mask-closable="false" :closable="false" :keyboard="false" :getContainer="setContainer">
      <div class="btn-close" @click="closeModal">
        <ta-icon type="close" class="close-color" />
      </div>
      <div class="pd-20">
        <ta-row :gutter="20">
          <ta-col :span="8">
            <div class="box">
              <div class="search-box">
                <ta-input-group v-if="isSelect" compact>
                  <ta-select v-model="searchType" style="width: 35%">
                    <ta-select-option :value="defaultProps.searchName">
                      人员
                    </ta-select-option>
                    <ta-select-option :value="defaultProps.searchOrg">
                      组织
                    </ta-select-option>
                  </ta-select>
                  <ta-input v-model="searchParam" placeholder="按回车搜索" style="width: 65%" @keyup.enter="onSearch" />
                </ta-input-group>
                <ta-input v-else ref="refSearchInput" v-model="searchParam" placeholder="搜索组织">
                  <ta-icon slot="prefix" type="search" class="icon-color" />
                  <ta-icon v-if="searchParam" slot="suffix" type="close-circle" class="icon-color" @click="emitEmpty" />
                </ta-input>
              </div>
              <div class="tree-box">
                <ta-e-tree v-if="load" ref="treeSelect" :load="load" lazy :props="defaultProps" :node-key="defaultProps.treeNodeKey" :filter-node-method="filterNode" :expand-on-click-node="false" highlight-current @node-click="handleNodeClick" />
                <ta-e-tree v-else ref="treeSelect" :data="userTreeData" :props="defaultProps" :node-key="defaultProps.treeNodeKey" :default-expanded-keys="defaultExpandedKey" :filter-node-method="filterNode" :expand-on-click-node="false" highlight-current @node-click="handleNodeClick" />
              </div>
            </div>
          </ta-col>
          <ta-col :span="16">
            <div class="box">
              <div v-if="(isMulti && isSelectAll) || includeChild" class="user-select-head-content">
                <a v-if="isMulti && isSelectAll" @click="handleSelectAll">选择全部</a>
                <ta-divider v-if="(isMulti && isSelectAll) && includeChild" type="vertical" />
                <ta-checkbox v-if="includeChild" :checked="checked" @change="fnCheckbox">
                  {{ includeChildTitle }}
                </ta-checkbox>
              </div>
              <show-user-list :id="id" ref="showUserList" :show-user-list-data="showUserList" :is-multi="isMulti" :is-show-head="(isMulti && isSelectAll) || includeChild" :props="props" :pagination="pagination && nextData" @clearSelectOption="selectOption = []" @more="fnMore" />
            </div>
          </ta-col>
        </ta-row>
      </div>
      <div class="show-user">
        <select-user-list :id="id" :props="props" @clearSelectOption="selectOption = []" />
      </div>
      <template slot="footer">
        <ta-button type="primary" @click="sendUserList">
          确定
        </ta-button>
      </template>
    </ta-modal>
  </div>
</template>
<script>
import {mapGetters, mapActions} from 'vuex'
import showUserList from './showUserList.vue'
import selectUserList from './selectUserList.vue'
import isEqual from 'lodash.isequal'
let _defaultProps = {
  treeNodeKey: 'value', // 每个树节点用来作为唯一标识的属性，整棵树应该是唯一的
  treeLabel: 'label', // 树节点的属性名称
  treeChildren: 'children', // 树子节点对象的属性名称
  treeDisabled: 'disabled', // 树指定节点选择框是否禁用为节点对象的某个属性值
  treeIsLeaf: 'isLeaf', // 树指定节点是否为叶子节点，仅在指定了 lazy 属性的情况下生效
  listKey: 'listKey', // 每条用户信息的唯一标识
  listTitle: 'listTitle', // 用户信息第一行显示内容
  listSubTitle: 'listSubTitle', // 用户信息第二行显示内容
  listDescription: 'listDescription', // 用户信息鼠标移上去显示描述信息
  searchName: 'name', // 面板搜索框搜索人员
  searchOrg: 'orgName', // 面板搜索框搜索组织
}
let timer = ''
export default {
  name: 'TaUserSelect',
  components: {showUserList, selectUserList},
  props: {
    /* 组件区分的唯一标识 */
    id: {
      type: [String, Number],
      required: true,
    },
    /* 配置选项 */
    props: {
      type: Object,
      default: function () {
        return _defaultProps
      },
    },
    userSelectData: {
      type: Array,
    },
    withTag: {
      type: Boolean,
      default: false,
    },
    /* 异步加载左侧树 */
    load: {
      type: Function,
    },
    /* 左侧树的数据 */
    userTreeData: {
      type: Array,
      default: () => [],
    },
    /* 右侧用户数据 */
    userListData: {
      type: Array,
      default: () => [],
    },
    /* 右侧用户默认数据 */
    defaultUserList: {
      type: Array,
      default: () => [],
    },
    /* 右侧用户加载更多 */
    pagination: {
      type: Boolean,
      default: false,
    },
    /* 弹出框标题 */
    title: {
      type: String,
      default: '用户选择',
    },
    /* 包含子部分的标题 */
    includeChildTitle: {
      type: String,
      default: '包含子部门人员',
    },
    /* 弹出框宽度 */
    width: {
      type: [String, Number],
      default: '800px',
    },
    /* 是否显示 */
    isShow: {
      type: Boolean,
      default: false,
    },
    /* 是否多选 */
    isMulti: {
      type: Boolean,
      default: true,
    },
    isSelectAll: {
      type: Boolean,
      default: true,
    },
    /* v-model */
    value: {
      type: Array,
      default: () => [],
    },
    isSelect: {
      type: Boolean,
      default: true,
    },
  },
  data () {
    return {
      searchType: '',
      searchParam: '',
      includeChild: false,
      showNodeKey: '',
      checked: false,
      pageNum: 1,
      showUserList: [],
      tagSelectVisible: false,
      selectOption: [],
      tempItem: {},
      modalShow: false,
      fetching: false,
      nextData: true,
    }
  },
  computed: {
    defaultProps () {
      return {
        treeNodeKey: this.props.treeNodeKey || _defaultProps.treeNodeKey,
        id: this.props.treeNodeKey || _defaultProps.treeNodeKey,
        children: this.props.treeChildren || _defaultProps.treeChildren,
        label: this.props.treeLabel || _defaultProps.treeLabel,
        disabled: this.props.treeDisabled || _defaultProps.treeDisabled,
        isLeaf: this.props.treeIsLeaf || _defaultProps.treeIsLeaf,
        listKey: this.props.listKey || _defaultProps.listKey,
        listTitle: this.props.listTitle || _defaultProps.listTitle,
        listSubTitle: this.props.listSubTitle || _defaultProps.listSubTitle,
        listDescription: this.props.listDescription || _defaultProps.listDescription,
        searchName: this.props.searchName || _defaultProps.searchName,
        searchOrg: this.props.searchOrg || _defaultProps.searchOrg,
      }
    },
    defaultExpandedKey () {
      if (this.userTreeData[0] == undefined) {
        return []
      } else {
        if (this.userTreeData[0][this.defaultProps.treeNodeKey] == undefined) {
          return []
        } else {
          return [this.userTreeData[0][this.defaultProps.treeNodeKey]]
        }
      }
    },
    modalShowFlag () {
      if (this.withTag) {
        return this.modalShow
      } else {
        return this.isShow
      }
    },
    getUserListById () {
      return this.getUserList[this.id]
    },
    ...mapGetters('taUserSelect', ['getUserList']),
  },
  watch: {
    searchParam (val) {
      if (this.searchType == this.defaultProps.searchOrg || !this.isSelect) {
        this.$refs.treeSelect.filter(val)
      }
    },
    defaultUserList: {
      immediate: true,
      handler (val, oldVal) {
        if (oldVal && oldVal.length) {
          for (let i = 0; i < oldVal.length; i++) {
            this.deleteOneUser(oldVal[i])
          }
        }
        if (val && val.length) {
          this.addAllUser(this.defaultUserListById(val))
        }
      },
    },
    modalShowFlag (isShow) {
      if (isShow) {
        this.searchType = this.defaultProps.searchName
        this.showUserList = this.userListData
      }
      if (isShow && this.defaultUserList.length && !this.withTag) {
        this.addAllUser(this.defaultUserListById(this.defaultUserList))
      }
    },
    userListData (val) {
      this.nextData = true
      if (this.pageNum == 1) {
        this.showUserList = val
      } else {
        if (val && val.length) {
          this.showUserList = this.showUserList.concat(val)
        } else {
          this.pageNum--
          this.nextData = false
        }
      }
    },
    userSelectData (val) {
      this.fetching = false
    },
    getUserListById (val) {
      let temp = []
      if (val && val.length) {
        val.forEach((item) => { temp.push(item[this.defaultProps.listKey].toString()) })
      }
      this.selectOption = temp
      this.$emit('input', val)
    },
    value: {
      immediate: true,
      handler (val, oldVal) {
        if (!isEqual(val, this.getUserListById)) {
          this.deleteAllUser(this.id)
          if (val.length) {
            this.addAllUser(this.defaultUserListById(val))
          }
        }
      },
    },
  },
  methods: {
    /* tag部分 */
    filterOption (input, option) {
      return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
    },
    fnDeselect (value) {
      let temp = {}
      temp._userSelectId = this.id
      temp._listKey = this.defaultProps.listKey
      temp[this.defaultProps.listKey] = value
      this.deleteOneUser(temp)
    },
    fnSelect (value) {
      this.tempItem._userSelectId = this.id
      this.tempItem._listKey = this.defaultProps.listKey
      if (!this.isMulti) {
        this.selectOption = []
        this.deleteAllUser(this.id)
      }
      this.addOneUser(this.tempItem)
    },
    defaultUserListById (data) {
      for (let i = 0; i < data.length; i++) {
        data[i]._userSelectId = this.id
        data[i]._listKey = this.defaultProps.listKey
      }
      return data
    },
    selectSearch (value) {
      clearTimeout(timer)
      timer = setTimeout(() => {
        this.$emit('search', value)
        this.fetching = true
      }, 800)
    },
    /* 面板部分 */
    emitEmpty () {
      this.$refs.refSearchInput.focus()
      this.searchParam = ''
    },
    onSearch () {
      this.includeChild = false
      this.$emit('queryUserList', this.$refs.treeSelect.getCurrentKey(), false, this.pageNum, this.searchType, this.searchParam)
    },
    filterNode (value, data) {
      if (!value) return true
      return data[this.defaultProps.label].indexOf(value) !== -1
    },
    handleNodeClick (data) {
      this.includeChild = !!((data[this.defaultProps.children] && data[this.defaultProps.children].length) || !data[this.defaultProps.isLeaf])
      if (this.showNodeKey !== data[this.defaultProps.treeNodeKey]) {
        this.showNodeKey = data[this.defaultProps.treeNodeKey]
        this.checked = false
        this.pageNum = 1
        this.$emit('queryUserList', data[this.defaultProps.treeNodeKey], this.checked, this.pageNum, this.searchType, this.searchParam)
      }
    },
    closeModal () {
      this.includeChild = false
      this.showNodeKey = ''
      this.checked = false
      this.pageNum = 1
      this.showUserList = []
      this.modalShow = false
      this.searchType = this.defaultProps.searchName
      this.searchParam = ''
      if (!this.withTag) {
        this.selectOption = []
        this.deleteAllUser(this.id)
      }
      this.$emit('close')
    },
    sendUserList () {
      let result = this.getUserListById ? [...this.getUserListById] : []
      this.$emit('getUserListResult', result)
      this.closeModal()
    },
    ...mapActions('taUserSelect', ['addOneUser', 'addAllUser', 'deleteOneUser', 'deleteAllUser']),
    fnCheckbox (e) {
      this.checked = e.target.checked
      this.pageNum = 1
      this.$emit('queryUserList', this.showNodeKey, this.checked, this.pageNum, this.searchType, this.searchParam)
    },
    handleSelectAll () {
      this.$refs.showUserList.fnAddAllUser()
    },
    fnMore () {
      this.pageNum++
      this.$emit('queryUserList', this.showNodeKey, this.checked, this.pageNum, this.searchType, this.searchParam)
    },
    setContainer () {
      return document.getElementById('userSelect')
    },
  },
}
</script>
