<template>
  <div
    v-if="permission != 'n'"
    :class="[
      'inputs',
      formInputsDisplay == 'block'
        ? 'ht-form-inputs__block'
        : 'ht-form-inputs__inline',
    ]"
  >
    <input
      v-if="disabled && isValidate && !isMobile && !isSubCellReadOnly"
      v-model="valueDesc"
      v-validate="inputValidate"
      type="hidden"
      :name="inputName"
      :data-vv-as="name"
    />
    <template v-if="inputWriteable && !isMobile">
      <template v-if="isSubCellReadOnly">
        <input
          v-model="valueDesc"
          v-validate="inputValidate"
          type="hidden"
          :name="inputName"
          :data-vv-as="name"
        />
        <div class="sub-table-cell-readonly" @click="handleCellClick">
          <span>
            {{ valueDesc }}
          </span>
        </div>
      </template>
      <template v-else>
        <el-select
          ref="elSelect"
          v-model="valueDesc"
          v-validate="inputValidate"
          :name="inputName"
          :data-vv-as="name"
          :size="inputSize"
          :popper-class="popperClass"
          :clearable="clearable"
          :placeholder="placeholder"
          :style="styles"
          :filterable="filterable"
          :filter-method="filterMethod"
          :disabled="disabled || (permission && permission === 'd') || (permission_sub && permission_sub === 'd')"
          @visible-change="handleVisibleChange"
          :loading="loading"
          @focus="handleFocus"
          @clear="clear"
        >
          <el-option
            v-if="selectlist && selectlist.length > 0"
            :value="valueDesc"
          >
            <el-scrollbar style="height: 100%" class="tree-scrollbar">
              <el-tree
                ref="elTree"
                node-key="key"
                style="maxheight: 245px"
                :data="selectlist"
                :indent="indent"
                :highlight-current="true"
                :default-expand-all="true"
                :expand-on-click-node="false"
                :props="defaultProps"
                :filter-node-method="filterNode"
                @node-click="handleNodeClick"
              ></el-tree>
            </el-scrollbar>
          </el-option>
        </el-select>
      </template>
    </template>
    <div v-if="inputWriteable && isMobile">
      <van-cell
        v-if="inputWriteable"
        :is-link="!(readonly || disabled || (permission && permission === 'd'))"
        class="mobile-cell"
        @click="showDialog"
      >
        <template #default>
          <!-- 校验 -->
          <input
            v-model="value"
            v-validate="validateRules"
            type="hidden"
            :name="inputName"
            :data-vv-as="name"
          />
          <span v-if="value" class="cell-text">
            {{ valueDesc || value }}
          </span>
          <span v-if="!value" class="placeholder-class">
            {{ mobilePlaceholder('请选择') }}
          </span>
          <van-icon
            v-if="
              (value && !disabled) ||
              (value && !(permission && permission === 'd'))
            "
            name="clear"
            color="#bfbfbf"
            class="cell-close"
            @click.stop="$emit('input', '')"
          />
        </template>
      </van-cell>
      <van-popup
        v-model="isPopShow"
        round
        position="bottom"
        class="custom-van-pop"
      >
        <div class="pop-content">
          <van-cascader
            v-model="mobileSelect"
            :title="name"
            :options="selectlist"
            active-color="#409EFF"
            :field-names="fieldNames"
            @finish="onConfirm"
            @close="onCancel"
          />
        </div>
      </van-popup>
    </div>
    <ht-field-tail
      v-if="permission != 'n'"
      :field-name="inputName"
      :readonly="!inputWriteable"
      :input-value="valueDesc"
      :hyperlink="hyperlink"
    ></ht-field-tail>
  </div>
</template>
<script>
  import utils from '@/utils.js'
  import permission from '@/mixins/permission.js'
  import inputName from '@/mixins/inputName.js'
  import form from '@/mixins/form.js'
  import mobileMode from '@/mixins/mobileMode.js'
  import popupMode from '@/mixins/popupMode.js'
  import tableFieldReadOnly from '@/mixins/tableFieldReadOnly.js'

  export default {
    name: 'HtDictionary',
    mixins: [
      permission,
      inputName,
      form,
      mobileMode,
      popupMode('isPopShow'),
      tableFieldReadOnly,
    ],
    props: {
      value: String,
      dickey: {
        type: String,
        require: true,
      },
      popperClass: String,
      styles: {
        type: Object,
        default() {
          return {}
        },
      },
      clearable: {
        type: Boolean,
        default: true,
      },
      filterable: {
        type: Boolean,
        default: false,
      },
      indent: {
        type: Number,
        default: 8,
      },
      disabled: {
        type: Boolean,
        default: false,
      },
      hyperlink: Object,
      isValidate: {
        type: Boolean,
        default: false,
      },
    },
    data() {
      return {
        mobileSelect: '',
        isPopShow: false,
        selectlist: [],
        defaultProps: {
          children: 'children',
          label: 'name',
        },
        fieldNames: {
          text: 'name',
          children: 'children',
        },
        valueDesc: '',
        loading: false,
      }
    },
    computed: {
      inputVal: {
        get: function () {
          if (utils.isEmpty(this.value)) {
            return ''
          }
          this.findDesc(this.selectlist)
          return this.value
        },
        set: function (val) {
          this.$emit('input', val)
        },
      },
      validateRules() {
        return this.disabled && !this.isValidate ? '' : this.inputValidate
      },
    },
    watch: {
      value: {
        handler(val) {
          if (val) {
            this.valueDesc = val
            this.findDesc(this.selectlist)
          } else {
            this.valueDesc = ''
          }
        },
        deep: true,
        immediate: true,
      },
      dickey: {
        handler(val) {
          if (val) {
            this.loadOptions()
          }
        },
        deep: true,
        immediate: true,
      },
    },
    mounted() {
      this.loadOptions()
    },
    methods: {
      handleVisibleChange(val) {
        if (val && !this.valueDesc) {
          this.loadOptions()
        }
      },
      onConfirm({ selectedOptions }) {
        this.mobileSelect = selectedOptions
          .map((option) => option.text)
          .join('/')
        this.value = selectedOptions.map((option) => option.key).join('/')
        this.$emit('input', this.value)
        this.$nextTick(() => {
          this.findDesc(this.selectlist)
        })
        this.isPopShow = false
      },
      onCancel() {
        this.isPopShow = false
      },
      // 展示选择弹窗
      showDialog() {
        if (this.disabled || (this.permission && this.permission === 'd'))
          return
        this.mobileSelect = this.valueDesc || ''
        this.findDesc(this.selectlist)
        this.isPopShow = true
      },
      loadOptions() {
        if (this.dickey) {
          this.loading = true
          this.$requestConfig.getDictionaryByKey(this.dickey).then((resp) => {
            this.selectlist = resp
            this.loading = false
            if (this.value !== null && this.value !== undefined) {
              this.findDesc(resp)
            }
          })
        }
      },
      clear() {
        this.filterMethod('')
        this.$emit('input', '')
      },
      handleFocus() {
        if (!this.value) {
          this.clear()
        }
      },
      handleNodeClick(data) {
        this.inputVal = data.key
        this.valueDesc = data.name
        this.$refs.elSelect.blur()
        setTimeout(() => {
          this.$validator.validate(this.inputName)
        })
      },
      filterNode(value, data) {
        if (!value) return true
        return data.name.indexOf(value) !== -1
      },
      findDesc(list) {
        if (list && list.length > 0) {
          list.forEach((l) => {
            if (l.key == this.value) {
              this.valueDesc = l.name
              return
            }
            if (l.children && l.children.length > 0) {
              this.findDesc(l.children)
            } else {
              delete l.children
            }
          })
        }
      },
      filterMethod(query) {
        this.$refs.elTree.filter(query)
      },
    },
  }
</script>
<style lang="scss" scoped>
  div[aria-invalid='true'] {
    ::v-deep {
      .el-input__inner,
      .el-input__inner:focus {
        border-color: #f56c6c;
      }
    }
  }

  .inputs {
    ::v-deep {
      .el-select {
        width: 100%;
      }
    }
  }

  .el-select-dropdown__item.hover,
  .el-select-dropdown__item:hover {
    padding-right: 0;
    padding-left: 0;
    background-color: #fff;
  }

  .el-select-dropdown__item {
    font-size: 14px;
    padding: 0;
    position: relative;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: #606266;
    height: 100%;
    line-height: 34px;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    cursor: pointer;
  }

  li.el-select-dropdown__item.selected {
    font-weight: normal;
    padding-right: 0;
    padding-left: 0;
  }
  .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;
      }
      .placeholder-class {
        flex: 1;
        color: #bfbfbf;
        font-size: 14px;
        text-align: right;
      }
      .cell-close {
        margin-left: 8px;
      }
    }
  }
  .custom-van-pop {
    max-height: 80%;
    display: flex;
    flex-direction: column;
    .pop-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 12px 15px;
      .cancel {
        font-size: 14px;
        color: #8c8c8c;
      }
      .title {
        font-size: 17px;
        color: #1a1a1a;
        font-weight: bold;
      }
      .confirm {
        font-size: 14px;
        color: #3177ec;
      }
    }
    .pop-content {
      flex: 1;
      overflow: auto;
      -webkit-overflow-scrolling: touch;
      .van-radio-group {
        ::v-deep .radio-item {
          padding: 14px 15px;
          border-bottom: 1px solid #e6e6e6;
          .van-radio__label {
            margin-left: 12px;
            color: #262626;
            font-size: 14px;
          }
        }
        .radio-item:last-child {
          border-bottom: none;
        }
      }
    }
  }

  ::v-deep {
    .el-tree-node__content {
      height: 32px;
    }
  }
</style>
