<template>
  <div class="AiWechatSelecter" v-if="isReeset">
    <el-button
        v-if="!isHasSlot && !isShowUser"
        size="mini"
        type="primary"
        @click="showSelecter"
        :disabled="disabled">
      选择人员
    </el-button>
    <div v-if="isHasSlot" @click="isShow = true">
      <slot/>
    </div>
    <div class="AiWechatSelecter-userlist" v-if="!isHasSlot && !isChooseUnit && isShowUser && resetWechatStatus">
      <div class="user-item" v-for="(item, index) in value" :key="index">
        <img :src="item.avatar||'https://cdn.cunwuyun.cn/dvcp/h5/defaultAvatar.png'">
        <ai-open-data type="userName" :openid="item.id"/>
        <i class="iconfont iconwarning" @click="removeUser(index)" v-if="isAdd"/>
      </div>
      <div class="user-add" @click="isShow = true" v-if="isAdd">
        <div class="userlist-add__icon">
          <i class="el-icon-plus"></i>
        </div>
        <span>选择</span>
      </div>
    </div>
    <ai-dialog
      :title="isChooseUnit ? '选择部门' : '选择人员'"
      :visible.sync="isShow"
      width="900px"
      append-to-body
      :modal-append-to-body="false"
      :close-on-click-modal="false"
      @onConfirm="onConfirm">
      <div class="AiWechatSelecter-container">
        <div class="AiWechatSelecter-container__left">
          <div class="AiWechatSelecter-header">
            <div class="AiWechatSelecter-header__left">
              <h2 class="active">部门</h2>
            </div>
          </div>
          <el-scrollbar class="AiWechatSelecter-list">
            <ai-tree
              :filter-node-method="filterNode"
              ref="tree"
              show-checkbox
              :props="defaultProps"
              node-key="id"
              :default-checked-keys="defaultChecked"
              :data="unitList"
              :check-strictly="strictly"
              :default-expanded-keys="defaultExpanded"
              @check="onCheck"
              @check-change="onCheckChange">
              <div class="tree-container" slot-scope="{ data }">
                <div class="tree-container__user">
                  <div class="tree-user__item">
                    <template v-if="data.avatar">
                      <img :src="data.avatar">
                      <ai-open-data type="userName" :openid="data.id"/>
                    </template>
                    <ai-open-data v-else type="departmentName" :openid="data.id"/>
                  </div>
                </div>
              </div>
            </ai-tree>
          </el-scrollbar>
        </div>
        <div class="AiWechatSelecter-container__right">
          <div class="AiWechatSelecter-header AiWechatSelecter-header__right">
            <h2>已选择</h2>
            <el-button size="mini" icon="el-icon-delete" @click="clearAll">清空</el-button>
          </div>
          <el-scrollbar class="AiWechatSelecter-list">
            <div class="tags-wrapper" v-if="isTagChange">
              <el-tag
                  v-for="(item, index) in chooseUser"
                  :key="item.name"
                  closable
                  @close="onClose(item, index)"
                  size="small"
                  type="info">
                <ai-open-data v-if="!isChooseUnit" type="userName" :openid="item.id"/>
                <ai-open-data v-else type="departmentName" :openid="item.id"/>
              </el-tag>
            </div>
          </el-scrollbar>
        </div>
      </div>
    </ai-dialog>
  </div>
</template>

<script>
import tree from './tree/tree.vue'

export default {
  model: {
    prop: 'value',
    event: 'change',
  },

  components: {
    aiTree: tree
  },

  name: 'AiUserGet',
  props: {
    instance: Function,
    isMultiple: {
      type: Boolean,
      default: true
    },
    isChooseUnit: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    isShowUser: {
      type: Boolean,
      default: false
    },
    disabledList: {
      type: Array,
      default: () => {
        return []
      }
    },
    isStrictly: {
      type: Boolean,
      default: false
    },
    isAdd: {
      type: Boolean,
      default: true
    },
    value: {
      type: Array
    },
    rootId: {
      type: String,
      default: ''
    },
    props: {
      type: Object,
      default: () => {
        return {
          label: 'name',
          id: 'id'
        }
      }
    },
    sass: Boolean
  },

  data() {
    return {
      showUserList: [],
      chooseUser: [],
      isReeset: true,
      searchObj: {
        con: '',
        current: 1,
        size: 10,
        status: '',
      },
      defaultExpanded: [],
      defaultProps: {
        children: 'childrenDept',
        label: 'name'
      },
      isTagChange: true,
      unitName: '',
      unitList: [],
      isShow: false,
      resetWechatStatus: true
    }
  },

  computed: {
    isHasOptionSlot() {
      return this.$slots.option
    },

    isHasSlot() {
      return this.$slots.default
    },

    strictly () {
      return this.Strictly || !this.isMultiple
    },

    defaultChecked() {
      if (!this.value) {
        return []
      }

      this.chooseUser = JSON.parse(JSON.stringify(this.value.map(item => {
        return {
          ...item,
          id: item[this.props.id],
          name: item[this.props.label]
        }
      })))
      return this.value.map(v => v[this.props.id])
    }
  },

  watch: {
    unitName(val) {
      this.$refs.tree.filter(val)
    },

    isShow(val) {
      if (val) {
        this.chooseUser = JSON.parse(JSON.stringify(this.value.map(item => {
          return {
            ...item,
            id: item[this.props.id],
            name: item[this.props.label]
          }
        })))
      }
    }
  },

  mounted() {
    this.getTree()

    if (this.value.length && this.isShowUser) {
      this.showUserList = JSON.parse(JSON.stringify(this.value.map(item => {
        return {
          ...item,
          id: item[this.props.id],
          name: item[this.props.label]
        }
      })))
      this.chooseUser = JSON.parse(JSON.stringify(this.value.map(item => {
        return {
          ...item,
          id: item[this.props.id],
          name: item[this.props.label]
        }
      })))
    }
  },

  methods: {
    clearAll() {
      this.chooseUser.forEach(item => {
        this.$refs.tree.setMyChecked(item, false, true)
      })
      this.$refs.tree.setCheckedKeys([])
      this.chooseUser = []
    },

    showSelecter() {
      if (this.disabled) return

      this.isShow = true
    },

    // 重置组件
    reset() {
      this.isReeset = false

      this.$nextTick(() => {
        this.isReeset = true
      })
    },

    arrDeduplication(arr) {
      var hash = {}
      arr = arr.reduce(function (item, next) {
        hash[next.id] ? '' : hash[next.id] = item.push(next)
        return item
      }, [])

      return arr
    },

    onCheck (e) {
      if (this.isMultiple) return

      this.$nextTick(() => {
        this.$refs.tree.getCheckedKeys().forEach(v => {
          this.$refs.tree.setMyChecked(v, false, true)
        })
        this.$refs.tree.setMyChecked(e.id, true, true)
      })
    },

    onCheckChange(e, isChoosed, isSunChoosed) {
      this.$nextTick(() => {
        const list = this.$refs.tree.getCheckedNodes().filter(v => {
          if (!this.isChooseUnit) {
            return v.type === '0'
          }

          return true
        })
        if (!this.isChooseUnit) {
          this.chooseUser = this.arrDeduplication([
            ...list
          ])
          if (!isChoosed && !isSunChoosed) {
            const index = this.chooseUser.findIndex(v => v.id === e.id)

            if (index > -1) {
              this.chooseUser.splice(this.chooseUser.findIndex(v => v.id === e.id), 1)
              this.$refs.tree.setMyChecked(e, false, true)
            }

            return false
          }

          if (isChoosed) {
            this.$refs.tree.setMyChecked(e, isChoosed, true)
          } else {
            this.$refs.tree.setMyChecked(e, false, true)
          }
        }

        if (this.isChooseUnit) {
          this.chooseUser = list
        }
      })
    },

    removeUser(index) {
      this.chooseUser.splice(index, 1)

      this.$nextTick(() => {
        this.$emit('change', this.chooseUser)
        this.showUserList = JSON.parse(JSON.stringify(this.chooseUser))
      })
    },

    getTree() {
      this.instance.post(`/app/wxcp/wxuser/tree?rootId=${this.rootId}`).then(res => {
        if (res.code === 0) {
          if (this.isChooseUnit) {
            this.unitList = res.data
          } else {
            this.unitList = this.formatList(res.data)
          }
          if (!this.defaultChecked.length) {
            this.defaultExpanded = [res.data[0].id]
          } else {
            this.defaultExpanded = this.defaultChecked
          }
        }
      })
    },

    filterUser(userList) {
      return userList.map(v => {
        if (this.disabledList.indexOf(v.id) > -1) {
          v.disabled = true
        }

        return v
      })
    },

    formatList(list) {
      var arr = []
      for (let item of list) {
        if (item.childrenUser && item.childrenUser.length) {
          let userList = JSON.parse(JSON.stringify(item.childrenUser))
          if (this.disabledList.length) {
            userList = this.filterUser(userList)
          }

          if (item.childrenDept) {
            item.childrenDept = [
              ...item.childrenDept,
              ...userList
            ]
          } else {
            item.childrenDept = [
              ...userList
            ]
          }
          delete item.childrenUser
        }

        if (item.childrenDept && item.childrenDept.length) {
          this.formatList(item.childrenDept)
        }

        arr.push(item)
      }

      return arr
    },

    onClose(item, index) {
      this.isTagChange = false
      this.chooseUser.splice(index, 1)
      this.$refs.tree.setMyChecked(item, false, true);

      this.$nextTick(() => {
        this.isTagChange = true
        this.$store.dispatch('initOpenData')
      })
    },

    filterNode(value, data) {
      if (!value) return true

      return data.name.indexOf(value) !== -1
    },

    onConfirm() {
      if (!this.isMultiple && this.chooseUser.length > 1) {
        return this.$message.error('不能多选')
      }

      this.resetWechatStatus = false
      this.$emit('change', JSON.parse(JSON.stringify(this.chooseUser.map(item => {
        return {
          ...item,
          [this.props.id]: item.id,
          [this.props.label]: item.name
        }
      }))))
      this.showUserList = JSON.parse(JSON.stringify(this.chooseUser.map(item => {
        return {
          ...item,
          [this.props.id]: item.id,
          [this.props.label]: item.name
        }
      })))
      this.isShow = false
      this.$nextTick(() => {
        this.resetWechatStatus = true
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.AiWechatSelecter {
  box-sizing: border-box;

  .AiWechatSelecter-userlist {
    display: flex;
    align-items: center;
    flex-wrap: wrap;

    .user-add {
      margin-bottom: 6px;

      .userlist-add__icon {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 40px;
        height: 40px;
        margin-bottom: 4px;
        border-radius: 2px;
        border: 1px solid #CCCCCC;
        cursor: pointer;

        &:hover {
          opacity: 0.6;
        }

        i {
          color: #CCCCCC;
          font-size: 20px;
        }
      }

      span {
        display: block;
        width: 100%;
        line-height: 22px;
        text-align: center;
        color: #888888;
        font-size: 14px;
      }
    }

    .user-item {
      position: relative;
      margin-bottom: 6px;
      margin-right: 16px;
      width: 40px;
      text-align: center;
      display: flex;
      align-items: center;
      flex-direction: column;

      img {
        display: block;
        width: 40px;
        height: 40px;
        margin-bottom: 4px;
        border-radius: 2px;
        border: 1px solid #CCCCCC;
      }

      i {
        position: absolute;
        top: -7px;
        right: -5px;
        padding: 0 0 2px 2px;
        font-size: 16px;
        background: #fff;
        border-radius: 50%;
        cursor: pointer;

        &:hover {
          opacity: 0.6;
        }
      }

      .AiOpenData {
        display: block;
        width: 100%;
        line-height: 22px;
        text-align: center;
        color: #888888;
        font-size: 14px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        cursor: pointer;
      }
    }
  }
}

.AiWechatSelecter-container {
  display: flex;
  height: 480px;

  .tree-container {
    & > span {
      display: block;
      margin-bottom: 4px;
    }

    .tree-user__item {
      display: flex;
      align-items: center;
      margin-bottom: 10px;

      &:last-child {
        margin-bottom: 0;
      }
    }

    img {
      width: 27px;
      height: 27px;
      margin-right: 10px;
    }
  }

  :deep( .el-tree ){
    background: transparent;

    .el-tree-node {
      margin-bottom: 8px;

      &:last-child {
        margin-bottom: 0;
      }
    }

    .el-tree-node__content {
      height: auto;
      margin-top: 2px;
      // align-items: inherit;
    }

    .el-tree-node__expand-icon {
      height: 24px;
    }
  }

  .mask-btn__wrapper {
    position: relative;
  }

  .mask-btn {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 1;
  }

  .userlist-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
    padding: 0 17px;
    cursor: pointer;
    user-select: none;

    :deep( .el-checkbox__label ){
      display: none;
    }

    .userlist-item__left {
      display: flex;
      align-items: center;

      span {
        color: #222222;
        font-size: 14px;
      }

      img {
        width: 40px;
        height: 40px;
        margin-right: 8px;
      }
    }
  }

  & > div {
    width: 280px;
    background: #FCFCFC;
    border: 1px solid #D0D4DC;
  }

  .AiWechatSelecter-list {
    height: calc(100% - 40px);
    padding: 8px 0;

    :deep( .el-scrollbar__wrap ){
      margin-bottom: 0 !important;
      overflow-x: hidden;
    }
  }

  .AiWechatSelecter-container__left {
    flex: 1;
  }

  .AiWechatSelecter-container__right {
    flex: 1;
    margin-left: 20px;

    .AiWechatSelecter-list {
      .tags-wrapper {
        padding: 0 8px;
        display: flex;
        flex-wrap: wrap;
      }

      .el-tag {
        margin: 0 8px 8px 0;
        color: #222222;
        font-size: 14px;
        display: flex;
        align-items: center;
        width: fit-content;

        .AiOpenData {
          height: unset;
        }
      }
    }
  }

  .AiWechatSelecter-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 40px;
    padding: 0 8px 0 0;
    border-bottom: 1px solid #D0D4DC;
    background: #F5F7FA;

    .AiWechatSelecter-header__left {
      display: flex;
      align-items: center;

      h2 {
        width: 60px;
        height: 100%;
        line-height: 40px;
        color: #222222;
        font-size: 14px;
        text-align: center;
        cursor: pointer;
        border-bottom: 2px solid transparent;

        &.active {
          color: $primaryColor;
          border-color: $primaryColor;
        }
      }
    }

    .el-button {
      height: 28px;
      padding: 7px 5px;
    }

    .el-input {
      width: 160px;
    }
  }

  .AiWechatSelecter-header__right {
    padding: 0 8px;

    h2 {
      color: #222222;
      font-size: 14px;
      text-align: center;
    }
  }
}
</style>
