<template>
  <div
    v-if="permission !== 'n'"
    :style="{
      width: isMobile
        ? '100%'
        : formInputsDisplay == 'block'
        ? '100%'
        : '220px',
    }"
    :class="[
      'inputs',
      'ht-form__sunOrSub',
      formInputsDisplay == 'block'
        ? 'ht-form-inputs__block'
        : 'ht-form-inputs__inline',
    ]"
  >
    <template v-if="isSubCellReadOnly && inputWriteable">
      <input
        v-if="isSubCellReadOnly && inputWriteable && isValidate"
        v-validate="inputValidate"
        :value="value"
        type="hidden"
        :name="inputName"
        :data-vv-as="name"
      />
      <div
        class="sub-table-cell-readonly el-select"
        :style="{
          height: 'fit-content',
          mixHeight: '32px',
        }"
        @click="handleCellClick()"
      >
        <span
          v-if="selectors && selectors.length"
          style="width: calc(100% - 34px)"
          class="tag-wrap"
        >
          <span
            v-for="(item, index) in currentShowData"
            :key="`${item.fullname}${index}`"
            class="el-tag el-tag--info el-tag--small"
          >
            <span class="el-select__tags-text">
              {{ item.fullname }}
            </span>
          </span>
          <el-tooltip
            v-if="inputWriteable && selectors && selectors.length > 2"
            class="item"
            effect="dark"
            :content="inputTooltipName"
            placement="top"
            popper-class="tooltip-width"
          >
            <span class="el-tag el-tag--info el-tag--small" @click.stop>
              <span class="el-select__tags-text">
                + {{ selectors.length - 2 }}
              </span>
            </span>
          </el-tooltip>
        </span>
      </div>
    </template>
    <template v-else>
      <div
        v-if="!isMobile"
        class="el-select"
        :class="{ 'has-value': !disabled && value }"
        style="width: 100%"
        @click="showDialog"
      >
        <input
          v-if="disabled && isValidate"
          v-model="value"
          v-validate="inputValidate"
          type="hidden"
          :name="inputName"
          :data-vv-as="name"
        />
        <div
          ref="tagSpans"
          class="user-selector_block"
          :class="{
            'el-select__tags_readonly': !inputWriteable,
            'el-select__tags': inputWriteable,
            'is-disabled-tags': disabled,
            'is-print': isPrintMode,
          }"
        >
          <span v-if="selectors && selectors.length" class="tag-wrap">
            <span
              v-for="(item, index) in currentShowData"
              :key="`${item.fullname}${index}`"
              class="el-tag--small"
              :class="[
                !inputWriteable && !disabled ? 'el-tag--light' : 'el-tag--info',
                !isPrintMode && 'el-tag',
              ]"
              :style="{
                'border-color': !inputWriteable && !disabled ? '#d9ecff' : '',
              }"
              @click.stop
            >
              <span v-if="inputWriteable && !disabled">
                <span class="el-select__tags-text">{{ item.fullname }}</span>
                <i
                  v-if="inputWriteable"
                  class="el-tag__close el-icon-close"
                  @click="handleRemove(item)"
                ></i>
              </span>
              <span
                v-else-if="hasHyperlink()"
                class="el-select__tags-text hyperlink_content"
                @click="openHyperlink"
              >
                {{ item.fullname }}
              </span>
              <span v-else class="el-select__tags-text">
                {{ item.fullname }}
              </span>
            </span>
            <el-tooltip
              v-if="inputWriteable && selectors && selectors.length > 2"
              class="item"
              effect="dark"
              :content="inputTooltipName"
              placement="top"
              popper-class="tooltip-width"
            >
              <span class="el-tag el-tag--info el-tag--small" @click.stop>
                <span class="el-select__tags-text">
                  + {{ selectors.length - 2 }}
                </span>
              </span>
            </el-tooltip>
          </span>
          <span v-if="!selectors.length && value" class="tag-wrap">
            <span
              v-for="(item, index) in value.split(',')"
              :key="index"
              class="el-tag el-tag--info el-tag--small"
              @click.stop
            >
              <span v-if="inputWriteable">
                <span class="el-select__tags-text">{{ item }}</span>
                <i
                  v-if="inputWriteable && !disabled"
                  class="el-tag__close el-icon-close"
                  @click="handleRemoveText(index)"
                ></i>
              </span>
              <span
                v-else-if="hasHyperlink()"
                class="el-select__tags-text hyperlink_content"
                @click="openHyperlink"
              >
                {{ item }}
              </span>
              <span v-else class="el-select__tags-text">{{ item }}</span>
            </span>
          </span>
        </div>
        <div
          v-if="inputWriteable"
          :class="[
            'el-input',
            'el-input--suffix',
            disabled ? 'is-disabled' : '',
          ]"
        >
          <input
            ref="inputEl"
            v-model="value"
            v-validate="inputValidate"
            :disabled="disabled"
            type="text"
            readonly="readonly"
            :name="inputName"
            :data-vv-as="name"
            autocomplete="off"
            class="el-input el-input__inner"
            :placeholder="placeholder"
            :style="{
              height: inputSuffixHeight + 'px',
              lineHeight: inputSuffixHeight + 'px',
            }"
          />
          <span class="el-input__suffix">
            <span class="el-input__suffix-inner">
              <i
                v-if="inputWriteable && !disabled"
                class="el-icon-circle-close clear-icon"
                @click.stop="clear"
              ></i>
              <ht-icon
                name="shenpiren"
                class="org-icon"
                :width="20"
                :height="20"
              />
            </span>
          </span>
        </div>
      </div>
      <div v-if="isMobile">
        <!-- 校验 -->
        <input
          v-model="value"
          v-validate="validateRules"
          class="mobile_field_input"
          type="hidden"
          :name="inputName"
          :data-vv-as="name"
        />
        <van-cell
          v-if="inputWriteable"
          is-link
          class="mobile-cell"
          @click="showDialog"
        >
          <template #default>
            <span v-if="value" class="cell-text">
              <span v-if="value.split(',').length < 4">{{ value }}</span>
              <span v-else>
                {{ value.split(',').splice(0, 3).join(',') }}&nbsp;共{{
                  value.split(',').length
                }}人
              </span>
            </span>
            <span v-if="!value" class="placeholder-class">
              {{ mobilePlaceholder('请选择') }}
            </span>
            <van-icon
              v-if="value && !disabled"
              name="clear"
              color="#bfbfbf"
              class="cell-close"
              @click.stop="$emit('valueChange', '')"
            />
          </template>

          <template #right-icon>
            <span v-if="!disabled" class="mobileCellRightIcon">
              <slot name="mobile-right-icon">
                <van-icon name="arrow" />
              </slot>
            </span>
          </template>
        </van-cell>
        <van-cell
          v-else
          class="mobile-cell"
          @click="
            value && value.split(',').length > 3 ? showAllPeople(value) : ''
          "
        >
          <template #default>
            <span v-if="value" class="cell-text">
              <span v-if="value.split(',').length < 4">{{ value }}</span>
              <span v-else>
                {{ value.split(',').splice(0, 3).join(',') }}&nbsp;共{{
                  value.split(',').length
                }}人
              </span>
            </span>
            <span v-if="!value" class="placeholder-class"></span>
          </template>
          <template v-if="value && value.split(',').length > 3" #right-icon>
            <span class="mobileCellRightIcon">
              <slot name="mobile-right-icon">
                <van-icon name="arrow" />
              </slot>
            </span>
          </template>
        </van-cell>
      </div>
      <ht-field-tail
        :field-name="inputName"
        :input-value="value"
        :hyperlink="hyperlink"
        :data-vv-as="name"
      />
      <user-selector-dialog
        v-if="!isMobile"
        ref="userSelectorDialog"
        v-model="selectors"
        :title="title"
        :append-to-body="appendToBody"
        :data="data"
        :pagination="pagination"
        :select-label="selectLabel"
        :quick-search-props="quickSearchProps"
        :single="single"
        :search-placeholder="searchPlaceholder"
        :primary-field="primaryField"
        :mode="mode"
        :current-policy-id="currentPolicyId"
        :current-role-id="currentRoleId"
        :max-length="maxLength"
        @filter-type-change="(type) => $emit('filter-type-change', type)"
        @search="(word) => $emit('search', word)"
        @reset="() => $emit('reset')"
        @row-click="(row) => $emit('row-click', row)"
        @page-change="(page) => $emit('page-change', page)"
        @size-change="(size) => $emit('size-change', size)"
        @select-data="(data) => $emit('select-data', data)"
        @contact-group-change="(group) => $emit('contact-group-change', group)"
        @load-org-user="(org) => $emit('load-org-user', org)"
        @load-policy-user="(policy) => $emit('load-policy-user', policy)"
        @load-role-user="(role) => $emit('load-role-user', role)"
      />
      <user-selector-mobile-dialog
        v-else
        ref="userSelectorMobileDialog"
        v-model="selectors"
        :title="title"
        :append-to-body="appendToBody"
        :data="data"
        :mode="mode"
        :pagination="pagination"
        :select-label="selectLabel"
        :quick-search-props="quickSearchProps"
        :single="single"
        :search-placeholder="searchPlaceholder"
        :primary-field="primaryField"
        :current-policy-id="currentPolicyId"
        :filter-type="filterType"
        :selectors-cache="selectorsCache"
        :range="range"
        :current-role-id="currentRoleId"
        @filter-type-change="(type) => $emit('filter-type-change', type)"
        @search="(word) => $emit('search', word)"
        @reset="() => $emit('reset')"
        @row-click="(row) => $emit('row-click', row)"
        @select-data="handleSelectData"
        @page-change="(page) => $emit('page-change', page)"
        @load-policy-user="(policy) => $emit('load-policy-user', policy)"
        @contact-group-change="(group) => $emit('contact-group-change', group)"
        @load-org="(data, page, fn) => $emit('load-org', data, page, fn)"
        @load-role-user="(role) => $emit('load-role-user', role)"
      />
      <!-- 超链接弹框 -->
      <ht-template-iframe-dialog ref="dialogIframe"></ht-template-iframe-dialog>
      <LookAllPeople v-if="isMobile" ref="LookAllPeople"></LookAllPeople>
    </template>
  </div>
</template>
<script>
  import utils from '@/utils.js'
  import inputName from '@/mixins/inputName.js'
  import permission from '@/mixins/permission.js'
  import mobileMode from '@/mixins/mobileMode.js'
  import HtFieldTail from '../../FieldTail/index'

  import LookAllPeople from '../../LookAllPeople/index'
  import UserSelectorDialog from './UserSelectorDialog.vue'
  import UserSelectorMobileDialog from './UserSelectorMobileDialog.vue'
  import { setTimeout } from 'timers'
  import hyperlinkHandler from '@/mixins/hyperlinkHandler.js'
  import tableFieldReadOnly from '@/mixins/tableFieldReadOnly.js'
  export default {
    name: 'HtUserSelector',
    components: {
      HtFieldTail,
      UserSelectorDialog,
      UserSelectorMobileDialog,
      LookAllPeople,
    },
    mixins: [
      inputName,
      permission,
      mobileMode,
      hyperlinkHandler,
      tableFieldReadOnly,
    ],
    props: {
      range: Object,
      searchPlaceholder: {
        type: String,
        default: '用户名称、账号',
      },
      value: String,
      single: {
        type: Boolean,
        default: false,
      },
      config: Object,
      data: {
        type: Array,
        default: () => {
          return []
        },
      },
      pagination: {
        type: Object,
        default: () => {
          return {
            page: 1,
            pageSize: 50,
            total: 0,
          }
        },
      },
      selectLabel: {
        type: String,
        default: 'fullname',
      },
      quickSearchProps: {
        type: String,
        required: true,
      },
      appendToBody: {
        type: Boolean,
        default: true,
      },
      formInputsDisplay: {
        type: String,
        default: 'inline',
      },
      title: {
        type: String,
        default: '选择用户',
      },
      mode: {
        type: String,
      },
      currentPolicyId: {
        type: String,
        default: '',
      },
      currentRoleId: {
        type: String,
        default: '',
      },
      filterType: {
        type: String,
        default: '',
      },
      disabled: {
        type: Boolean,
        default: false,
      },
      isValidate: {
        type: Boolean,
        default: false,
      },
      isPrintMode: {
        type: Boolean,
        default: false,
      },
      maxLength: {
        // 最大选中长度  0 为不限制
        type: Number,
        default: 0,
      },
    },
    provide() {
      return {
        dialogInstance: this,
      }
    },
    data() {
      return {
        inputSuffixHeight: 30,
        selectors: [],
        selectorsCache: [],
      }
    },
    computed: {
      primaryField: function () {
        return this.config && this.config.hasOwnProperty('id')
          ? 'id'
          : this.config && this.config.hasOwnProperty('account')
          ? 'account'
          : this.selectLabel
      },
      inputTooltipName() {
        let data = this.selectors.map((item) => item.fullname).join(',') || ''
        return data
      },
      currentShowData() {
        return this.inputWriteable ? this.selectors.slice(0, 2) : this.selectors
      },
      validateRules() {
        return this.disabled && !this.isValidate ? '' : this.inputValidate
      },
    },
    watch: {
      // 当所选择的数据发生变化时，同步到v-model中
      selectors: function (newVal) {
        let ary = [],
          idAry = [],
          fullnameAry = [],
          mobileAry = [],
          emailAry = [],
          postNameAry = [],
          orgNameAry = [],
          accountAry = []

        if (newVal && newVal.constructor === Array && newVal.length > 0) {
          newVal.forEach((m) => {
            ary.push(m.fullname)
            if (m.hasOwnProperty('id')) {
              idAry.push(m.id)
            }
            if (m.hasOwnProperty('fullname')) {
              fullnameAry.push(m.fullname)
            }
            if (m.hasOwnProperty('account')) {
              accountAry.push(m.account)
            }
            if (m.hasOwnProperty('mobile')) {
              mobileAry.push(m.mobile)
            }
            if (m.hasOwnProperty('email')) {
              emailAry.push(m.email)
            }
            if (m.hasOwnProperty('postname')) {
              postNameAry.push(m.postname)
            }
            if (m.hasOwnProperty('orgname')) {
              orgNameAry.push(m.orgname)
            }
          })
        }
        if (this.config) {
          // 配置了id的绑定关系，则回填到指定属性上
          if (this.config.hasOwnProperty('id')) {
            utils.setValueByConfigKey(this, this.config, 'id', idAry.join(','))
          }
          // 配置了fullname的绑定关系，则回填到指定的属性上
          if (this.config.hasOwnProperty('fullname')) {
            utils.setValueByConfigKey(
              this,
              this.config,
              'fullname',
              fullnameAry.join(',')
            )
          }
          // 配置了account的绑定关系，则回填到指定的属性上
          if (this.config.hasOwnProperty('account')) {
            utils.setValueByConfigKey(
              this,
              this.config,
              'account',
              accountAry.join(',')
            )
          }
          // 配置了mobile的绑定关系，则回填到指定的属性上
          if (this.config.hasOwnProperty('mobile')) {
            utils.setValueByConfigKey(
              this,
              this.config,
              'mobile',
              mobileAry.join(',')
            )
          }
          // 配置了email的绑定关系，则回填到指定的属性上
          if (this.config.hasOwnProperty('email')) {
            utils.setValueByConfigKey(
              this,
              this.config,
              'email',
              emailAry.join(',')
            )
          }

          // 配置了post绑定关系，则回填到指定的属性上
          if (this.config.hasOwnProperty('postname')) {
            utils.setValueByConfigKey(
              this,
              this.config,
              'postname',
              postNameAry.join(',')
            )
          }

          // 配置了org绑定关系，则回填到指定的属性上
          if (this.config.hasOwnProperty('orgname')) {
            utils.setValueByConfigKey(
              this,
              this.config,
              'orgname',
              orgNameAry.join(',')
            )
          }
        } else {
          this.$emit('change', newVal)
        }
        // 通过valueChange事件发布值变更消息
        this.$emit('valueChange', ary.join(','), newVal)
        setTimeout(() => {
          if (newVal.length > 0) {
            this.calacInputSuffixHeight()
          } else {
            this.inputSuffixHeight = 30
          }
          if (this.$refs.inputEl) {
            this.$refs.inputEl.focus({
              preventScroll: true,
            })
            this.$refs.inputEl.blur()
          }
        }, 10)
      },
      value: {
        handler(val) {
          // 父级传递进来的value发生变更时，需要同步到当前所选数据中
          this.valueInit()
        },
        immediate: true,
        deep: true,
      },
    },
    mounted() {
      // 组件第一次挂载时，同步value到当前所选数据中
      this.valueInit()
    },
    methods: {
      handleSelectData(data) {
        this.selectorsCache = data
        this.$emit('select-data', data)
      },
      // 同步value到当前所选数据中
      valueInit() {
        let tmpAry = []
        if (this.value) {
          let idAry = [],
            accountAry = [],
            fullnameAry = [],
            mobileAry = [],
            postNameAry = [],
            orgNameAry = [],
            emailAry = []
          if (this.config) {
            // 配置了id绑定关系，则获取id的值
            if (this.config.hasOwnProperty('id')) {
              let idVal = utils.getValueByConfigKey(this, this.config, 'id')
              if (idVal) {
                idAry = idVal.split(',').trim()
              }
            }
            // 配置了fullname绑定关系，则获取fullname的值
            if (this.config.hasOwnProperty('fullname')) {
              let fullnameVal = utils.getValueByConfigKey(
                this,
                this.config,
                'fullname'
              )
              if (fullnameVal) {
                fullnameAry = fullnameVal.split(',').trim()
              }
            }

            // 配置了account绑定关系，则获取account的值
            if (this.config.hasOwnProperty('account')) {
              let accountVal = utils.getValueByConfigKey(
                this,
                this.config,
                'account'
              )
              if (accountVal) {
                accountAry = accountVal.split(',').trim()
              }
            }

            // 配置了mobile绑定关系，则获取mobile的值
            if (this.config.hasOwnProperty('mobile')) {
              let mobileVal = utils.getValueByConfigKey(
                this,
                this.config,
                'mobile'
              )
              if (mobileVal) {
                mobileAry = mobileVal.split(',').trim()
              }
            }

            // 配置了post绑定关系，则获取post的值
            if (this.config.hasOwnProperty('postname')) {
              let postVal = utils.getValueByConfigKey(
                this,
                this.config,
                'postname'
              )
              if (postVal) {
                postNameAry = postVal.split(',').trim()
              }
            }

            // 配置了org绑定关系，则获取org的值
            if (this.config.hasOwnProperty('orgname')) {
              let orgVal = utils.getValueByConfigKey(
                this,
                this.config,
                'orgname'
              )
              if (orgVal) {
                orgNameAry = orgVal.split(',').trim()
              }
            }

            // 配置了email绑定关系，则获取email的值
            if (this.config.hasOwnProperty('email')) {
              let emailVal = utils.getValueByConfigKey(
                this,
                this.config,
                'email'
              )
              if (emailVal) {
                emailAry = emailVal.split(',').trim()
              }
            }
          }
          // 将fullname、id、code从逗号分割的字符串解析为json对象格式的数组
          let valAry = this.value.split(',').trim()
          valAry.forEach((m, index) => {
            let item = { fullname: m }
            if (idAry.length > index) {
              item['id'] = idAry[index]
            }
            if (accountAry.length > index) {
              item['account'] = accountAry[index]
            }
            if (fullnameAry.length > index) {
              item['fullname'] = fullnameAry[index]
            }
            if (mobileAry.length > index) {
              item['mobile'] = mobileAry[index]
            }
            if (emailAry.length > index) {
              item['email'] = emailAry[index]
            }
            if (postNameAry.length > index) {
              item['postname'] = postNameAry[index]
            }
            if (orgNameAry.length > index) {
              item['orgname'] = orgNameAry[index]
            }
            tmpAry.push(item)
          })
        }
        // 对数组做深度对比，如果值不完全相等，则进行赋值操作
        if (!utils.arrayEquals(tmpAry, this.selectors)) {
          this.selectors = tmpAry
        }
      },
      showDialog() {
        if (!this.inputWriteable || this.disabled) {
          return
        }
        if (this.isMobile) {
          this.$refs.userSelectorMobileDialog.showDialog()
        } else {
          this.$refs.userSelectorDialog.showDialog()
        }
      },
      showAllPeople(value) {
        this.$refs.LookAllPeople.showDialog(value)
      },
      handleRemove(item) {
        this.selectors.remove(item)
      },
      clear() {
        this.selectors = []
        this.inputSuffixHeight = 30
        this.$emit('clear')
      },
      // 更新当前输入框的高度来适配已选数据的高度
      calacInputSuffixHeight() {
        if (!this.$refs.tagSpans) return
        if (this.$refs.tagSpans.offsetHeight) {
          this.inputSuffixHeight = this.$refs.tagSpans.offsetHeight + 5
        } else {
          this.inputSuffixHeight = 30
        }
      },
      handleRemoveText(index) {
        if (!this.value) {
          return
        }
        let values = this.value.split(',')
        values.splice(index, 1)
        this.$emit('input', values.join(','))
      },
    },
  }
</script>
<style lang="scss" scoped>
  @import '@/styles/selector.scss';
  .mobile_field_input {
    border: none;
  }
  .mobile_field_input[aria-invalid='true'] {
    border: none;
  }
  .user-selector_block {
    width: calc(100% - 38px);
    background: #fff;
    margin-left: 1px;
  }
  .el-select__tags_readonly {
    position: relative;
    top: 50%;
    background: unset !important;
  }
  .is-disabled-tags {
    background: unset !important;
    cursor: not-allowed;
  }
  .el-input__inner[aria-invalid='true'] {
    border-color: #f56c6c;
  }
  .hyperlink_content {
    color: var(--themeColor);
    cursor: pointer;
  }

  .el-input__suffix {
    display: flex;
    flex-direction: column;
    justify-content: center;
    .el-input__suffix-inner {
      border-left: 1px solid #d9d9d9;
      padding-left: 8px;
      padding-right: 3px;
      height: calc(100% - 2px);
      display: flex;
      align-items: center;
    }
  }
  .mobile-cell {
    min-height: 32px;
    padding: 0;
    align-items: center;
    &::after {
      display: none;
    }
    .van-cell__value {
      display: flex;
      align-items: center;
      .cell-text {
        flex: 1;
        word-break: break-all;
        color: #262626;
        font-size: 14px;
        text-align: right;
        padding: 12px 0;
      }

      .placeholder-class {
        flex: 1;
        color: #bfbfbf;
        font-size: 14px;
        text-align: right;
      }
      .cell-close {
        margin-left: 8px;
      }
    }
  }
  .mobile-readonly {
    text-align: right;
    line-height: 24px;
    padding: 12px 0;
  }
</style>
