<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" class="tag-wrap">
          <span
            v-for="(item, index) in currentShowData"
            :key="index"
            class="el-tag el-tag--info el-tag--small"
          >
            <span class="el-select__tags-text">
              {{ item.name }}
            </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"
        style="width: 100%; min-width: 180px"
        class="el-select"
        :class="{ 'has-value': !disabled && selectors.length > 0 }"
        @click="showDialog"
      >
        <input
          v-if="disabled && isValidate"
          v-model="value"
          v-validate="inputValidate"
          type="hidden"
          :name="inputName"
        />
        <div
          ref="tagSpans"
          style="width: calc(100% - 34px)"
          :class="{
            'el-select__tags_readonly': !inputWriteable,
            'el-select__tags': inputWriteable,
            'is-print': isPrintMode,
          }"
        >
          <span v-if="selectors && selectors.length" class="tag-wrap">
            <span
              v-for="(item, index) in currentShowData"
              :key="`${item.name}${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">
                <span class="el-select__tags-text">{{ item.name }}</span>
                <i
                  v-if="inputWriteable && !disabled"
                  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.name }}
              </span>
              <span v-else class="el-select__tags-text">{{ item.name }}</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>
        <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__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"
          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"
      />
      <post-selector-dialog
        v-if="!isMobile"
        ref="postSelectorDialog"
        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"
        @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="(data) => $emit('select-data', data)"
        @page-change="(page) => $emit('page-change', page)"
        @size-change="(size) => $emit('size-change', size)"
        @load-org-post="(org) => $emit('load-org-post', org)"
        @load-policy-post="(policy) => $emit('load-policy-post', policy)"
      />
      <post-selector-mobile-dialog
        v-else
        ref="postSelectorMobileDialog"
        v-model="selectors"
        :title="title"
        :append-to-body="appendToBody"
        :data="data"
        :pagination="pagination"
        :select-label="selectLabel"
        :single="single"
        :search-placeholder="searchPlaceholder"
        :primary-field="primaryField"
        :current-policy-id="currentPolicyId"
        :selectors-cache="selectorsCache"
        :filter-type="filterType"
        :range="range"
        :quick-search-props="quickSearchProps"
        @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-org-post="(org) => $emit('load-org-post', org)"
        @load-policy-post="(policy) => $emit('load-policy-post', policy)"
      />
      <!-- 超链接弹框 -->
      <ht-template-iframe-dialog ref="dialogIframe"></ht-template-iframe-dialog>
      <LookAllPeople
        v-if="isMobile"
        ref="LookAllPeople"
        title="已选岗位"
      ></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 { setTimeout } from 'timers'
  import PostSelectorDialog from './PostSelectorDialog.vue'
  import PostSelectorMobileDialog from './PostSelectorMobileDialog.vue'
  import hyperlinkHandler from '@/mixins/hyperlinkHandler.js'
  import LookAllPeople from '../../LookAllPeople/index'
  import tableFieldReadOnly from '@/mixins/tableFieldReadOnly.js'
  export default {
    name: 'HtPostSelector',
    components: {
      HtFieldTail,
      PostSelectorDialog,
      PostSelectorMobileDialog,
      LookAllPeople,
    },
    mixins: [
      inputName,
      permission,
      mobileMode,
      hyperlinkHandler,
      tableFieldReadOnly,
    ],
    props: {
      range: Object,
      filterType: String,
      searchPlaceholder: {
        type: String,
        default: '名称、编码、路径',
      },
      value: {
        type: String,
        default: '',
      },
      single: {
        type: Boolean,
        default: false,
      },
      config: {
        type: Object,
        default: null,
      },
      data: {
        type: Array,
        default: () => {
          return []
        },
      },
      pagination: {
        type: Object,
        default: () => {
          return {
            page: 1,
            pageSize: 50,
            total: 0,
          }
        },
      },
      selectLabel: {
        type: String,
        default: 'jobName',
      },
      quickSearchProps: {
        type: String,
        required: true,
      },
      appendToBody: {
        type: Boolean,
        default: false,
      },
      formInputsDisplay: {
        type: String,
        default: 'inline',
      },
      title: {
        type: String,
        default: '选择岗位',
      },
      mode: {
        type: String,
      },
      currentPolicyId: {
        type: String,
        default: '',
      },
      disabled: {
        type: Boolean,
        default: false,
      },
      isPrintMode: {
        type: Boolean,
        default: false,
      },
      isValidate: {
        type: Boolean,
        default: false,
      },
    },
    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('code')
          ? 'code'
          : this.selectLabel
      },
      inputTooltipName() {
        let data = this.selectors.map((item) => item.name).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 = [],
          codeAry = [],
          nameAry = []
        if (newVal && newVal.constructor === Array && newVal.length > 0) {
          newVal.forEach((m) => {
            ary.push(m.name)
            if (m.hasOwnProperty('id')) {
              idAry.push(m.id)
            }
            if (m.hasOwnProperty('code')) {
              codeAry.push(m.code)
            }
            if (m.hasOwnProperty('name')) {
              nameAry.push(m.name)
            }
          })
        }
        if (this.config) {
          // 配置了id的绑定关系，则回填到指定属性上
          if (this.config.hasOwnProperty('id')) {
            utils.setValueByConfigKey(this, this.config, 'id', idAry.join(','))
          }
          // 配置了code的绑定关系，则回填到指定的属性上
          if (this.config.hasOwnProperty('code')) {
            utils.setValueByConfigKey(
              this,
              this.config,
              'code',
              codeAry.join(',')
            )
          }
          // 配置了name的绑定关系，则回填到指定的属性上
          if (this.config.hasOwnProperty('name')) {
            utils.setValueByConfigKey(
              this,
              this.config,
              'name',
              nameAry.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: function () {
        // 父级传递进来的value发生变更时，需要同步到当前所选数据中
        this.valueInit()
      },
    },
    mounted() {
      // 组件第一次挂载时，同步value到当前所选数据中
      this.valueInit()
    },
    methods: {
      showAllPeople(value) {
        this.$refs.LookAllPeople.showDialog(value)
      },
      handleSelectData(data) {
        this.selectorsCache = data
        this.$emit('select-data', data)
      },
      // 同步value到当前所选数据中
      valueInit() {
        let tmpAry = []
        if (this.value) {
          let idAry = [],
            codeAry = [],
            nameAry = []
          if (this.config) {
            // 配置了id绑定关系，则获取id的值
            if (this.config.hasOwnProperty('id')) {
              let idVal = utils.getValueByConfigKey(this, this.config, 'id')
              if (idVal) {
                idAry = idVal.split(',').trim()
              }
            }
            // 配置了name绑定关系，则获取name的值
            if (this.config.hasOwnProperty('name')) {
              let nameVal = utils.getValueByConfigKey(this, this.config, 'name')
              if (nameVal) {
                nameAry = nameVal.split(',').trim()
              }
            }

            // 配置了code绑定关系，则获取code的值
            if (this.config.hasOwnProperty('code')) {
              let codeVal = utils.getValueByConfigKey(this, this.config, 'code')
              if (codeVal) {
                codeAry = codeVal.split(',').trim()
              }
            }
          }
          // 将name、id、code从逗号分割的字符串解析为json对象格式的数组
          let valAry = this.value.split(',').trim()
          valAry.forEach((m, index) => {
            let item = { name: m }
            if (idAry.length > index) {
              item['id'] = idAry[index]
            }
            if (nameAry.length > index) {
              item['name'] = nameAry[index]
            }
            if (codeAry.length > index) {
              item['code'] = codeAry[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.postSelectorMobileDialog.showDialog()
        } else {
          this.$refs.postSelectorDialog.showDialog()
        }
      },
      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
        }
      },
    },
  }
</script>
<style lang="scss" scoped>
  @import '~@/styles/selector.scss';
  .mobile_field_input {
    border: none;
  }
  .mobile_field_input[aria-invalid='true'] {
    border: none;
  }
  .el-select__tags {
    background: #fff;
    margin-left: 1px;
  }

  .el-select__tags_readonly {
    position: relative;
    top: 50%;
  }

  .el-input__inner[aria-invalid='true'] {
    border-color: #f56c6c;
  }
  .hyperlink_content {
    color: var(--themeColor);
    cursor: pointer;
  }
  ::v-deep .el-main {
    padding-top: 0;
    padding-bottom: 0;
  }
  .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__title {
      width: 1px;
      flex-grow: 0;
    }
    .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>
