<template>
  <div
    v-if="permission != 'n'"
    :class="[
      'inputs',
      formInputsDisplay == 'block'
        ? 'ht-form-inputs__block'
        : 'ht-form-inputs__inline',
    ]"
  >
    <div v-if="inputWriteable">
      <template v-if="isSubCellReadOnly">
        <input
          v-validate="inputValidate"
          :value="inputVal"
          type="hidden"
          :name="inputName"
          :data-vv-as="name"
        />
        <div class="sub-table-cell-readonly" @click="handleCellClick">
          <span>
            {{ inputValToJson }}
          </span>
        </div>
      </template>
      <template v-else>
        <el-select
          v-if="!isMobile"
          ref="fuzzySearch"
          v-model="inputVal"
          v-validate="inputValidate"
          class="ht-tag_select"
          style="width: 100%"
          :size="inputSize"
          :filterable="filterable"
          :remote="filterable"
          :remote-method="remoteMethod"
          :multiple="multiple"
          clearable
          :name="inputName"
          :data-vv-as="name"
          @focus="focusSelectValue"
          @visible-change="visibleChange"
        >
          <div v-loading="loading">
            <el-option
              v-for="item in options"
              :key="item.id"
              :label="item.name"
              :value="item.name"
            ></el-option>
          </div>

          <div class="text-center">
            <a class="text-normal">
              <el-pagination
                layout="prev, pager, next"
                :page-size="pagination.pageSize"
                :pager-count="5"
                :current-page="pagination.page"
                :total="pagination.total"
                @current-change="currentChange"
              ></el-pagination>
            </a>
          </div>
          <div class="ht-tag__append">
            <el-button
              v-if="creatingTag"
              size="small"
              type="primary"
              plain
              style="width: calc(100% - 20px); margin: 0 10px"
              @click="add"
            >
              添加
            </el-button>
          </div>
          <template v-if="creatingTag" slot="empty">
            <el-button
              v-if="creatingTag"
              size="small"
              type="primary"
              style="width: calc(100% - 20px); margin: 0 10px"
              plain
              @click="add"
            >
              添加
            </el-button>
          </template>
        </el-select>
        <div v-else>
          <div style="min-height: 32px; position: relative">
            <!-- 校验 -->
            <input
              v-model="inputVal"
              v-validate="inputValidate"
              type="hidden"
              :name="inputName"
              :data-vv-as="name"
            />
            <van-cell
              v-validate="!inputVal && inputValidate"
              class="cell"
              :name="inputName"
              :data-vv-as="name"
              title=" "
              :is-link="!(readonly || disabled)"
              @click="handleShowPicker"
            >
              <div class="flex">
                <div v-if="inputVal" class="cell-text">
                  <span v-if="typeof inputVal === 'string'">
                    {{ inputVal }}
                  </span>
                  <van-tag
                    v-for="(item, index) in inputVal"
                    v-else
                    :key="index"
                    class="tag"
                    plain
                    color="#409EFF"
                    style="font-size: 12px; margin-left: 8px"
                  >
                    {{ item }}
                  </van-tag>
                </div>
                <div v-else class="placeholder-class">
                  {{ mobilePlaceholder('请选择') }}
                </div>
                <van-icon
                  v-if="inputVal"
                  name="clear"
                  color="#bfbfbf"
                  @click.stop="clearSelect"
                />
              </div>
            </van-cell>
          </div>
          <mobileTag
            ref="mobileTag"
            v-model="inputVal"
            :multiple="multiple"
            :tag-value="tagValue"
            :options="options"
            :expand="expand"
            :filterable="filterable"
            @add="add"
            @search="search"
          />
        </div>
      </template>
    </div>
    <ht-field-tail
      :field-name="inputName"
      :readonly="!inputWriteable"
      :input-value="inputVal"
      :tag-format-value="tagValue"
      :is-tag="true"
    />
  </div>
</template>

<script>
  import permission from '@/mixins/permission.js'
  import linkage from '@/mixins/linkage.js'
  import inputName from '@/mixins/inputName.js'
  import form from '@/mixins/form.js'
  import mobileMode from '@/mixins/mobileMode.js'
  import mobileTag from './mobileTag.vue'
  import tableFieldReadOnly from '@/mixins/tableFieldReadOnly.js'

  export default {
    name: 'HtTag',
    components: {
      mobileTag,
    },
    mixins: [
      permission,
      inputName,
      linkage,
      form,
      mobileMode,
      tableFieldReadOnly,
    ],
    props: {
      value: String,
      filterable: {
        type: Boolean,
        default: false,
      },
      expand: {
        type: Boolean,
        default: false,
      },
      tagKey: String,
      multiple: {
        type: Boolean,
        default: false,
      },
    },
    data() {
      return {
        options: [],
        pagination: {
          pageSize: 5,
          page: 1,
          total: 0,
        },
        mobilePagination: {
          page: 1,
          pageSize: -1,
        },
        loading: false,
        currentQuery: '',
        isExistTag: true,
      }
    },
    computed: {
      inputVal: {
        set(value) {
          if (value && this.multiple) {
            this.$emit('input', value.join(','))
          } else {
            this.$emit('input', value)
          }
        },
        get() {
          if (this.value && this.multiple) {
            return this.value.split(',')
          }
          return this.value
        },
      },
      tagValue() {
        return this.inputVal && this.inputVal.constructor == Array
          ? this.inputVal
          : this.inputVal && this.inputVal.constructor == String
          ? [this.inputVal]
          : []
      },
      creatingTag() {
        return this.expand && this.currentQuery !== '' && !this.isExistTag
      },
    },
    watch: {
      currentQuery: {
        handler(newVal) {
          if (this.options) {
            this.isExistTag = this.options.some((item) => item.name == newVal)
          } else {
            this.isExistTag = false
          }
        },
      },
      inputVal: {
        deep: true,
        immediate: true,
        handler: function (newVal) {
          const list = this.selectlist ? this.selectlist : this.options
          let currentSelected = ''
          if (list) {
            if (this.multiple) {
              currentSelected = list.filter((i) => newVal.includes(i.name))
              if (currentSelected) {
                this.selectStr = currentSelected.map((i) => i.name).join(',')
              }
            } else {
              currentSelected = list.find((i) => i.name === newVal)
              this.selectStr = (currentSelected && currentSelected.name) || ''
            }
          }
          this.selectResult = newVal || []
        },
      },
    },
    mounted() {
      window.addEventListener('scroll', this.handleScroll, true)
      this.search()
    },
    beforeDestroy() {
      window.removeEventListener('scroll', this.handleScroll, true)
    },
    methods: {
      handleScroll() {
        this.currentQuery = ''
        this.$refs.fuzzySearch && this.$refs.fuzzySearch.blur()
      },
      focusSelectValue() {
        if (this.$refs.fuzzySearch.$refs.input) {
          this.$refs.fuzzySearch.$refs.input.blur = () => {
            this.currentQuery = ''
            this.search()
          }
        }
      },
      visibleChange(flag) {
        //单选时输入框关闭时重新搜索内容
        if (!flag && !this.multiple) {
          this.currentQuery = ''
          this.search()
        }
      },
      remoteMethod(query) {
        this.currentQuery = query
        let param = {
          pageBean: this.isMobile ? this.mobilePagination : this.pagination,
          querys: [
            {
              property: 'type_key_',
              value: this.tagKey,
              group: 'query',
              operation: 'EQUAL',
              relation: 'AND',
            },
          ],
        }
        if (!this.isMobile && query) {
          param.querys.push({
            property: 'name_',
            value: query,
            group: 'query',
            operation: 'LIKE',
            relation: 'AND',
          })
        }
        this.loading = true
        this.$requestConfig
          .getTagList(param)
          .then((data) => {
            this.options = data.rows
            this.isExistTag = this.options.some(
              (item) => item.name == this.currentQuery
            )
            this.pagination = {
              pageSize: data.pageSize,
              page: data.page,
              total: data.total,
            }
          })
          .finally(() => {
            this.loading = false
          })
      },
      currentChange(page) {
        this.pagination.page = page
        this.remoteMethod(this.currentQuery)
      },
      add(currentQuery) {
        let param = {
          name: this.currentQuery || currentQuery,
          typeKey: this.tagKey,
        }
        this.$requestConfig
          .saveTag(param)
          .then((data) => {
            if (data.state) {
              this.messageToast('success', '添加成功')
              this.remoteMethod(this.currentQuery)
            } else {
              // this.messageToast('error', data.message)
              throw new Error(data.message)
            }
          })
          .catch(() => {
            this.messageToast('error', '标签已存在，不可重复添加')
          })
      },
      search(val) {
        let param = {
          pageBean: this.isMobile ? this.mobilePagination : this.pagination,
          querys: [
            {
              property: 'type_key_',
              value: this.tagKey,
              group: 'query',
              operation: 'EQUAL',
              relation: 'AND',
            },
          ],
        }
        if (val && this.isMobile) {
          param.querys.push({
            property: 'name_',
            value: val,
            group: 'query',
            operation: 'LIKE',
            relation: 'AND',
          })
        }
        this.$requestConfig.getTagList(param).then((data) => {
          this.options = data.rows
          this.pagination = {
            pageSize: data.pageSize,
            page: data.page,
            total: data.total,
          }
        })
      },
      messageToast(type, message) {
        if (this.isMobile && type === 'error') {
          type = 'danger'
        }
        return this.isMobile
          ? this.$notify({ type: type, message })
          : this.$message({ type: type, message: message })
      },
      handleShowPicker() {
        this.$refs.mobileTag.handleShowPicker()
      },
      clearSelect() {
        this.inputVal = this.multiple ? [] : ''
        this.$emit('input', '')
        this.$emit('change', '')
        this.handlerValidate()
      },
      handlerValidate() {
        setTimeout(() => {
          this.$validator.validate(this.inputName)
        }, 10)
      },
    },
  }
</script>

<style lang="scss" scoped>
  .text-center {
    position: sticky;
    background: #fff;
    height: 30px;
    top: 0;
    z-index: 1;
    text-align: center;
  }
  div[aria-invalid='true'] {
    ::v-deep {
      .el-input__inner,
      .el-input__inner:focus {
        border-color: #f56c6c;
      }
    }
  }
  .ht-tag__append {
    text-align: center;
    padding: 5px 0;
  }
  .ht-tag__empty {
    background: #f5f7fa;
    text-align: center;
    margin: 5px 0;
    padding: 8px 0;
    cursor: pointer;
  }
  /* 移动端 */
  .mobile_field_input {
    border: none;
    width: 100%;
    height: 32px;
    position: absolute;
  }
  .van-cell[aria-invalid='true'] {
    border: none;
  }
  .cell {
    .flex {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      i {
        margin-left: 5px;
      }
    }
  }
  .van-cell {
    min-height: 32px;
    padding-top: 3px;
    padding-bottom: 0;
    padding-right: 0;
    &::after {
      display: none;
    }
    .van-cell__title {
      width: 1px;
      flex-grow: 0;
    }
  }
  .placeholder-class {
    color: #bfbfbf;
    font-size: 14px;
    text-align: right;
  }
  .cell-text {
    word-break: break-all;
    color: #262626;
    font-size: 14px;
    text-align: right;
  }
  .mobile-cell {
    padding: 0;
    display: flex;
    align-items: center;
    .van-cell__value {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      .cell-text {
        color: #262626;
        font-size: 14px;
        text-align: right;
      }
      .cell-close {
        margin-left: 4px;
      }
    }
    .placeholder-class {
      color: #bfbfbf;
      font-size: 14px;
      text-align: right;
    }
  }
</style>
