<template>
  <van-field
    ref="input"
    v-model="inputValue"
    :label="label"
    :name="name"
    :size="size"
    :placeholder="placeholder"
    :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"
    readonly
    @click-input="onClick"
  >
    <template #label>
      {{ label }}<van-icon v-if="desc && descPosition==='lableIcon'" name="warning" class="ibps-dialog-icon" @click="showDesc(label,desc)" />
    </template>
    <template v-if="editable" #right-icon>
      <van-icon
        v-if="showClear"
        name="clear"
        class="van-field__clear"
        @click.native.stop="onRightIconClick"
      />
      <van-icon
        v-else
        :name="showPopup?'arrow-up':'arrow-down'"
        @click.native.stop="onClick"
      />
      <van-popup
        v-model="showPopup"
        get-container="body"
        position="bottom"
        @close="handleClose"
      >
        <ibps-picker-toolbar
          :title="title"
          :cancel-button-text="cancelButtonText"
          :confirm-button-text="confirmButtonText"
          @cancel="onCancel"
          @title="onTitleClick"
          @confirm="onConfirm"
        />
        <div class="ibps-popup-wrapper">
          <van-checkbox-group v-model="checkbox">
            <van-cell-group>
              <van-cell
                v-for="(option,index) in options"
                :key="option[valueKey]"
                :title="option[labelKey]"
                clickable
                @click.stop="toggle(index,option['disabled'])"
              >
                <template #right-icon>
                  <van-checkbox
                    ref="checkboxes"
                    :name="option[valueKey]"
                    :disabled="option['disabled']"
                  />
                </template>
              </van-cell>
            </van-cell-group>
          </van-checkbox-group>
        </div>
      </van-popup>
    </template>
    <!--展示字段-->
    <template v-if="$utils.isNotEmpty(selectedOptions)" #input>
      <div class="van-field__control">
        <!-- <van-tag
          v-for="(item,index) in selectedOptions "
          :key="item[valueKey]+index"
          type="primary"
          class="ibps-tag-span"
          :color="color"
          :text-color="textColor"
          :plain="plain"
          size="medium"
        >{{ item[labelKey] }}</van-tag> -->

        <van-tag
          v-for="(item,index) in selectedOptions.slice(0,num) "
          :key="item[valueKey]+index"
          class="ibps-tag-span"
          :color="color"
          :text-color="textColor"
          :plain="plain"
          size="medium"
        ><div class="ibps-ellipsis">{{ item[labelKey] }}</div></van-tag>
        <van-tag
          v-if="selectedOptions.length>num"
          :color="color"
          :text-color="textColor"
          :plain="plain"
          size="medium"
        >+{{ selectedOptions.length-num }}</van-tag>

      </div>
    </template>
  </van-field>
</template>

<script>
import { isDef } from 'vant/lib/utils'
import FieldMixin from '@/mixins/field'
import IbpsPickerToolbar from '@/components/ibps-picker-toolbar'
import ActionUtils from '@/utils/action'

export default {
  name: 'ibps-checkbox',
  components: {
    IbpsPickerToolbar
  },
  mixins: [FieldMixin],
  props: {
    options: {
      type: Array,
      default: () => {
        return []
      }
    },
    store: { //  返回值类型 string 字符串类型, array: 数组。
      type: String,
      default: 'string',
      validator: function(value) {
        return ['array', 'string'].indexOf(value) !== -1
      }
    },
    storeSeparator: { //  返回值分割符，对于设置字符串类型的分隔符有效
      type: String,
      default: ','
    },
    valueKey: {
      type: String,
      default: 'value'
    },
    labelKey: {
      type: String,
      default: 'label'
    },
    otherOptionKey: {
      type: String,
      default: 'include_other_option'
    },
    otherOptionValue: {
      type: String,
      default: ''
    },
    showToolbar: {
      type: Boolean,
      default: true
    },
    cancelButtonText: String,
    confirmButtonText: String,

    color: {
      type: String,
      default: '#D6EAFE'
    },
    textColor: {
      type: String,
      default: '#3396FB'
    },
    plain: {
      type: Boolean,
      default: false
    },
    desc: String
  },
  data() {
    return {
      checkbox: [],
      inputValue: '',
      selectedOptions: [],
      showPopup: false,
      otherOption: '',
      otherOptionPlaceholder: '其他选项',
      num: 3 // 默认最多显示3个选项
    }
  },
  computed: {
    showClear() {
      return this.clearable && this.$utils.isNotEmpty(this.value) && isDef(this.value) && this.editable
    },
    title() {
      const length = this.checkbox.length
      return length > 0 ? this.$t('components.checkbox.title', { length: length }) : ''
    },
    cacheOptions() {
      const { options } = this
      if (!options || options.length === 0) { return {} }
      const cacheOptions = {}
      for (let i = 0; i < options.length; i++) {
        const option = options[i]
        if (option instanceof String) {
          cacheOptions[option] = {
            [this.labelKey]: option
          }
        } else {
          cacheOptions[option[this.valueKey] ] = option
        }
      }
      return cacheOptions
    },
    hasOtherOption() {
      return this.isIncludeOtherOption(this.value)
    }
  },
  watch: {
    value: {
      handler(val, oldVal) {
        this.initSelectedOptions()
        this._setInputValue()
      },
      immediate: true
    },
    checkbox() {
      this._setInputValue()
      this.validate()
    },
    otherOption() {
      this.$emit('change-other-option', this.otherOption)
    }
  },
  created() {
    this._getNumByWidth()
  },
  methods: {
    showDesc(title, message) {
      ActionUtils.descDialog({ title, message })
    },
    _getNumByWidth() {
      const width = document.documentElement.clientWidth
      if (width >= 375) this.num = 3
      else this.num = 2
    },
    initSelectedOptions() {
      const arrayValue = this.getArrayValue()
      const options = []
      if (this.$utils.isNotEmpty(arrayValue)) {
        arrayValue.forEach(v => {
          const data = this.cacheOptions[v]
          if (this.$utils.isNotEmpty(data)) {
            options.push(data)
          }
        })
      }
      this.selectedOptions = options
      this.setOtherOptionValue()
    },
    getArrayValue() {
      if (this.store === 'string') {
        if (this.$utils.isEmpty(this.value)) {
          return []
        } else {
          return this.value.split(this.storeSeparator)
        }
      } else {
        return this.value || []
      }
    },
    getStoreValue(value) {
      if (this.store === 'string') {
        return value.join(this.storeSeparator)
      } else {
        return value || []
      }
    },
    onClick() {
      if (!this.editable) { return }
      this.checkbox = this.getArrayValue()
      this.showPopup = true
    },
    handleClose() {
      this.showPopup = false
    },
    toggle(index, disabled) {
      if (disabled) return
      this.$refs.checkboxes[index].toggle()
    },
    onTitleClick() {
      if (!this.$listeners['title-click']) { // 标题事件
        this.checkbox = []
      }
      this.$emit('title-click', this)
    },
    removeData(index) {
      this.checkbox.splice(index, 1)
      this.$emit('input', this.getStoreValue(this.checkbox))
    },
    onCancel() {
      this.showPopup = false
      this.$emit('cancel', this)
    },
    onConfirm() {
      this.showPopup = false
      this.$emit('input', this.getStoreValue(this.checkbox))
      this.$emit('confirm', this)
    },
    onRightIconClick() {
      this.showClear ? this.onClear() : this.onClick()
    },
    onClear() {
      this.otherOption = ''
      this.$emit('input', '')
    },
    setOtherOptionValue() {
      if (this.hasOtherOption) {
        this.otherOption = this.otherOptionValue
      }
    },
    isIncludeOtherOption(value) {
      if (this.cacheOptions[value]) {
        return !!this.cacheOptions[value][this.otherOptionKey]
      }
      return false
    },
    changeOtherOption(value) {
      this.$emit('change-other-option', value)
    }
  }
}
</script>
