<template>
  <div class="van-cell ibps-p-0">
    <van-field
      ref="input"
      v-model="inputValue"
      :label="label"
      :name="name"
      :size="size"
      :border="border"
      :disabled="disabled"
      :required="required"
      :clearable="clearable"
      :clickable="clickable"
      :is-link="isLink"
      :error="error"
      :error-message="errorMessage"

      :arrow-direction="arrowDirection"
      :label-class="labelClass"
      :label-width="labelWidth"
      :label-align="labelAlign"
      :input-align="inputAlign"
      :error-message-align="errorMessageAlign"
      :autosize="autosize"
      :left-icon="leftIcon"
      :right-icon="rightIcon"
      :icon-prefix="iconPrefix"
      :rules="editable?rules:null"
      class="ibps-selector"
      readonly
      @click-input="onClick"
    >
      <template #label>
        {{ label }}<van-icon v-if="desc && descPosition==='lableIcon'" name="warning" class="ibps-dialog-icon" @click="$action.descDialog({ title:label, message:desc })" />
      </template>
      <template #input>
        <!-- {{selectedData}} -->
        <!-- <div style="display:none">{{ $utils.isEmpty(selectedData) }}</div> -->
        <template v-if="selectedData==[]">
          <template v-if="editable">
            <!-- <van-icon
              slot="left-icon"
              name="add-o"
              class="van-cell__left-icon"
            /> -->
            <!-- <div class="van-field__body">
              <input :placeholder="defaultPlaceholder" class="van-field__control" readonly>
            </div> -->
            <van-tag
              v-for="(item,index) in selectedData.slice(0,num) "
              :key="item[valueKey]"
              class="ibps-tag-span ibps-mr-8"
              :color="color"
              :text-color="textColor"
              :plain="plain"
            >
              <template #default>
                <div :class="multiple?'ibps-ellipsis':''">{{ item[labelKey] }}</div>
                <div v-if="editable" class="ibps-tag-close"><van-icon name="clear" @click.stop="removeData(index)" /></div>
              </template>
            </van-tag>
            <van-tag
              v-if="selectedData.length>num"
              :color="color"
              :text-color="textColor"
              :plain="plain"
            >+{{ selectedData.length-num }}</van-tag>
          </template>
        </template>
        <template v-else>
          <div class="van-field__control">
            <van-tag
              v-for="(item,index) in selectedData.slice(0,num) "
              :key="item[valueKey]"
              class="ibps-tag-span ibps-mr-8"
              :color="color"
              :text-color="textColor"
              :plain="plain"
            >
              <template #default>
                <div :class="multiple?'ibps-ellipsis':''">{{ item[labelKey] }}</div>
                <div v-if="editable" class="ibps-tag-close"><van-icon name="clear" @click.stop="removeData(index)" /></div>
              </template>
            </van-tag>
            <van-tag
              v-if="selectedData.length>num"
              :color="color"
              :text-color="textColor"
              :plain="plain"
            >+{{ selectedData.length-num }}</van-tag>

          </div>
        </template>

      </template>
      <template #right-icon>
        <van-icon name="arrow" class="ibps-gray-b2" @click="onClick" />
      </template>
    </van-field>

    <!-- <template v-if="editable">  // 下一版本初始化数据自己处理-->
    <!--用户选择器 -->
    <employee-selector
      v-if="type ==='employee' || type ==='user'"
      :show-popup="showPopup"
      :value="selectedValue"
      :multiple="multiple"

      :custom-party-type-options="customPartyTypeOptions"
      :current-org-id="currentOrgId"
      :party-type-id="partyTypeId"
      :script="script"
      :party-type-scope="partyTypeScope"
      :is-use-scope="true"

      :left-text="leftText"
      :value-key="valueKey"
      :label-key="labelKey"

      :filter="fieldOptions && fieldOptions.filter"

      @init-data="initData"
      @cancel="onCancel"
      @confirm="onConfirm"
      @change-party-type="changePartyType "
      @callbackData="callbackData"
    />

    <!--组织选择器 -->
    <org-selector
      v-if="type ==='org'"
      :show-popup="showPopup"
      :value="selectedValue"
      :multiple="multiple"

      :left-text="leftText"
      :value-key="valueKey"
      :label-key="labelKey"

      :current-org-id="currentOrgId"
      :party-type-id="partyTypeId"
      :script="script"
      :is-use-scope="true"

      :other-filter="fieldOptions &&fieldOptions.other_filter"
      :other-filter-include-sub="fieldOptions &&fieldOptions.other_filter_include_sub"
      :other-filter-condition="fieldOptions &&fieldOptions.other_filter_condition"

      @init-data="initData"
      @cancel="onCancel"
      @confirm="onConfirm"
      @callbackData="callbackData"
    />

    <!--岗位选择器 -->
    <position-selector
      v-if="type ==='position'"
      :show-popup="showPopup"
      :value="selectedValue"
      :multiple="multiple"

      :left-text="leftText"
      :value-key="valueKey"
      :label-key="labelKey"

      :current-org-id="currentOrgId"
      :party-type-id="partyTypeId"
      :script="script"
      :is-use-scope="true"

      :other-filter="fieldOptions &&fieldOptions.other_filter"
      :other-filter-include-sub="fieldOptions &&fieldOptions.other_filter_include_sub"
      :other-filter-condition="fieldOptions &&fieldOptions.other_filter_condition"

      @init-data="initData"
      @cancel="onCancel"
      @confirm="onConfirm"
      @callbackData="callbackData"
    />

    <!--角色选择器 -->
    <role-selector
      v-if="type ==='role'"
      :show-popup="showPopup"
      :value="selectedValue"
      :multiple="multiple"

      :left-text="leftText"
      :value-key="valueKey"
      :label-key="labelKey"

      :current-org-id="currentOrgId"
      :party-type-id="partyTypeId"
      :script="script"
      :is-use-scope="true"

      :other-filter="fieldOptions &&fieldOptions.other_filter"
      :other-filter-include-sub="fieldOptions &&fieldOptions.other_filter_include_sub"
      :other-filter-condition="fieldOptions &&fieldOptions.other_filter_condition"

      @init-data="initData"
      @cancel="onCancel"
      @confirm="onConfirm"
      @callbackData="callbackData"
    />
    <!-- </template> -->
  </div>
</template>
<script>
import FieldMixin from '@/mixins/field'
import EmployeeSelector from './employee'
import OrgSelector from './org'
import PositionSelector from './position'
import RoleSelector from './role'

import i18n from '@/utils/i18n' // Internationalization 国际化
import { typeOptions as partyTypeOptions } from './constants'

export default {
  name: 'ibps-user-selector',
  components: {
    EmployeeSelector,
    OrgSelector,
    PositionSelector,
    RoleSelector
  },
  mixins: [FieldMixin],
  props: {
    multiple: Boolean,
    type: { // 选择器类型 user:用户选择器,org:组织选择器，position：岗位选择器，role：角色选择器
      type: String,
      required: true
    },
    store: { // 存储类型 对应[多选]有效，json： json字符串,id:只存储id， array：存储数组数据 ，arrayId: 字符串类型。
      type: String,
      default: 'json',
      validator: function(value) {
        return ['json', 'id', 'array', 'arrayId', 'bind'].indexOf(value) !== -1
      }
    },
    storeSeparator: { // 存储值分割符，对于设置字符串类型的分隔符
      type: String,
      default: ','
    },
    bindId: {
      type: String
    },
    leftText: {
      type: String,
      default: i18n.t('cancel')
    },
    idKey: {
      type: String,
      default: 'id'
    },
    parentIdKey: {
      type: String,
      default: 'parentId'
    },
    valueKey: {
      type: String,
      default: 'id'
    },
    labelKey: {
      type: String,
      default: 'name'
    },
    childrenKey: {
      type: String,
      default: 'children'
    },
    fieldOptions: {
      type: Object,
      default: () => {
        return {}
      }
    },
    color: {
      type: String,
      default: '#D6EAFE'
    },
    textColor: {
      type: String,
      default: '#3396FB'
    },
    plain: {
      type: Boolean,
      default: false
    },
    filter: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      showPopup: false, // 弹窗
      selectedData: [], // 选中的值
      selectedValue: [],
      bindIdValue: '',
      num: 3, // 默认最多显示3个选项
      partyTypeOptions: partyTypeOptions,
      customPartyTypeOptions: [],
      // 用户选择器条件
      condition: {
        org: {
          partyTypeId: '',
          currentOrgId: '',
          script: ''
        },
        position: {
          partyTypeId: '',
          currentOrgId: '',
          script: ''
        },
        role: {
          partyTypeId: '',
          currentOrgId: '',
          script: ''
        },
        group: {
          partyTypeId: '',
          currentOrgId: '',
          script: ''
        }
      },
      // 传递参数
      partyTypeId: '',
      currentOrgId: '',
      script: '',
      partyTypeScope: ''
    }
  },
  computed: {
    showClear() {
      return this.clearable && this.$utils.isNotEmpty(this.value) && this.isDef(this.value) && this.editable
    },
    defaultPlaceholder() {
      if (this.placeholder) { return this.placeholder }
      const type = this.type ? this.$t('components.selector.' + this.type) : ''
      return i18n.t('components.selector.placeholder', { type: type })
    }
  },
  watch: {
    value: {
      handler() {
        this.initSelectedData()
      },
      immediate: true
    },
    filter: {
      handler(val, oldVal) {
        // console.info(val, '==>>filter')
        this.filterScope(val)
      },
      immediate: true,
      deep: true
    }
  },
  created() {
    this._getNumByWidth()
  },
  mounted() {
    this.initSelectedData()
  },
  methods: {
    _getNumByWidth() {
      const width = document.documentElement.clientWidth
      if (width >= 375) this.num = 3
      else this.num = 2
    },
    _setInputValue() {
      this.inputValue = this.$utils.isNotEmpty(this.value) ? JSON.stringify(this.value) : ''
      setTimeout(() => {
        this.validate()
      }, 10)
    },
    initSelectedData() {
      this.selectedValue = this.getArrayValue(this.value, this.bindId)
      if (this.$utils.isEmpty(this.selectedValue)) {
        this.selectedData = []
      }
    },
    getArrayValue(value, bindId) {
      if (this.$utils.isEmpty(value)) {
        return []
      }
      if (this.store === 'json') { // json
        return this.parseJsonData(value)
      } else if (this.store === 'id') { // id
        // 可能是json数据
        if (this.$utils.isJSON(value)) {
          return this.parseJsonData(value)
        } else {
          return this.$utils.isString(value) ? value.split(this.storeSeparator) : []
        }
      } else if (this.store === 'arrayId') { // 数组id
        return value
      } else if (this.store === 'bind') { // 绑定id
        if (this.$utils.isJSON(value)) {
          return this.parseJsonData(value)
        } else {
          return this.$utils.isString(value) ? value.split(this.storeSeparator) : []
        }
      } else {
        return value.map((d) => {
          return d[this.valueKey]
        })
      }
    },
    parseJsonData(value) {
      try {
        const data = this.$utils.parseData(value)
        const result = []
        if (Array.isArray(data)) {
          data.forEach(d => {
            const node = d[this.valueKey]
            if (node) result.push(node)
          })
        } else {
          result.push(data[this.valueKey])
        }
        return result
      } catch (error) {
        console.warn(error)
        return []
      }
    },
    getStoreValue(value) {
      const res = []
      if (this.store === 'json') { // json
        if (this.$utils.isEmpty(value)) {
          return ''
        }
        value.forEach(v => {
          const o = {}
          o[this.valueKey] = v[this.valueKey]
          o[this.labelKey] = v[this.labelKey]
          res.push(o)
        })
        return JSON.stringify(res)
      } else if (this.store === 'id') { // id
        if (this.$utils.isEmpty(value)) {
          return ''
        }
        value.forEach(v => {
          res.push(v[this.valueKey])
        })
        return res.join(this.storeSeparator)
      } else if (this.store === 'arrayId') { // 数组id
        if (this.$utils.isEmpty(value)) {
          return []
        } else {
          return value.map((d) => {
            return d[this.valueKey]
          })
        }
      } else if (this.store === 'bind') { // 绑定id
        const res = []
        const bindIdValue = []
        value.forEach(v => {
          bindIdValue.push(v[this.valueKey])
          res.push(v[this.labelKey])
        })
        this.bindIdValue = bindIdValue.join(this.storeSeparator)

        // return res.join(this.storeSeparator)
        return this.bindIdValue
      } else { // 数组
        return value || []
      }
    },
    onClick() {
      if (!this.editable) { return }
      this.selectedValue = this.getArrayValue(this.value, this.bindId)
      this.showPopup = true
    },
    onCancel() {
      this.showPopup = false
    },
    onConfirm(selectedData) {
      if (this.$utils.isEmpty(selectedData)) {
        this.$notify({
          type: 'warning',
          message: '请选择！'
        })
        return
      }
      if (!this.multiple && this.$utils.isEmpty(selectedData[0])) {
        this.$notify({
          type: 'warning',
          message: '请选择！'
        })
        return
      }
      this.showPopup = false
      this.selectedData = selectedData
      this.$emit('input', this.getStoreValue(selectedData))
    },
    callbackData(selectedData) {
      this.emitInput(selectedData, this.type)
      this.showPopup = false
    },
    emitInput(value, type) {
      if (this.store === 'bind') {
        this.$nextTick(() => {
          this.$emit('bind-callback', value, type)
        })
      }
    },
    onRightIconClick() {
      this.showClear ? this.onClear() : this.onClick()
    },
    onClear() {
      this.$emit('input', [])
    },
    // 回调初始化数据
    initData(data) {
      this.selectedData = data
      this._setInputValue()
    },
    removeData(index) {
      this.selectedData.splice(index, 1)
      const mid = []
      this.selectedData.forEach((it, i) => {
        mid.push(it.id)
      })
      this.selectedValue.splice(0)
      this.selectedValue = mid
      this.$emit('input', this.getStoreValue(this.selectedData))
    },

    changePartyType(value) {
      const params = this.condition[value]
      this.partyTypeScope = value
      this.partyTypeId = params.partyTypeId
      this.currentOrgId = params.currentOrgId
      this.script = params.script
    },
    filterScope(val) {
      const existingTypeScope = []
      const typeScope = []
      val.forEach(v => {
        existingTypeScope.push(v.userType)
        this.filterSelectorType(v)
      })
      // 根据设置得范围类型切换选择器左树（或右树）下拉类型数据
      const partyTypeOptions = JSON.parse(JSON.stringify(this.partyTypeOptions))
      partyTypeOptions.forEach((f, i) => {
        if (existingTypeScope.includes(f.value)) {
          typeScope.push(f)
        }
      })
      this.customPartyTypeOptions = typeScope
      // 初始化查询范围条件
      if (this.$utils.isNotEmpty(typeScope)) {
        this.currentOrgId = this.condition[typeScope[0].value].currentOrgId
        this.partyTypeId = this.condition[typeScope[0].value].partyTypeId
        this.script = this.condition[typeScope[0].value].script
      }
    },
    // 根据选择器类型分发筛选条件并储存
    filterSelectorType(val) {
      switch (val.type) {
        case 'user':
          this.getUserSelectorCondition(val, val.userType)
          break
        case 'org':
          this.getOrgSelectorCondition(val)
          break
        case 'position':
          this.getPositionSelectorCondition(val)
          break
        case 'role':
          this.getRoleSelectorCondition(val)
          break
      }
      // console.info(this.condition, '=>>this.condition')
    },
    getUserSelectorCondition(val, type) {
      this.condition[type] ? this.condition[type].partyTypeId = val.descVal : null
      switch (val.descVal) {
        case '1':
          break
        case '2':
        case '3':
          this.condition[type].currentOrgId = val.partyId
          break
        case 'script':
          this.condition[type].script = val.scriptContent
          break
      }
    },
    // 获取组织选择器条件
    getOrgSelectorCondition(val) {
      this.partyTypeId = val.descVal
      switch (val.descVal) {
        case '1':
          break
        case '2':
        case '3':
          this.currentOrgId = val.partyId
          break
        case 'script':
          this.script = val.scriptContent
          break
      }
    },
    // 获取岗位选择器条件
    getPositionSelectorCondition(val) {
      this.partyTypeId = val.descVal
      switch (val.descVal) {
        case '1':
          break
        case '2':
        case '3':
          this.currentOrgId = val.partyId
          break
        case 'script':
          this.script = val.scriptContent
          break
      }
    },
    // 获取角色选择器条件
    getRoleSelectorCondition(val) {
      // console.info(val, '=>>获取角色选择器条件')
      this.partyTypeId = val.descVal
      switch (val.descVal) {
        case '1':
          break
        case '2':
        case '3':
          this.currentOrgId = val.partyId
          break
        case 'script':
          this.script = val.scriptContent
          break
      }
    }
  }
}
</script>
<style lang="scss" scoped>
  .ibps-tag-close{
    position: absolute;
    right: -6px;
    top: -6px;
    color:  #74B7FC;
  }
</style>

