<template>
  <li
    @mouseenter="hoverItem"
    @click.stop="selectOptionClick"
    class="qf-option"
    v-show="visible"
    :class="{
      'selected': itemSelected,
      'is-disabled': disabled || groupDisabled || limitReached,
      'hover': hover
    }">
    <qf-checkbox v-if="isMultiple" :value="itemSelected"></qf-checkbox>
    <slot>
      <span>{{ currentLabel }}</span>
    </slot>
    <div v-if="created">{{ t('qf.option.new') }}</div>
  </li>
</template>

<script>
  import ObjectUtil from '../../util/object';
  import QfCheckbox from '../../checkbox';
  import LocaleMixin from '../../locale/mixin';

  export default {
    name: 'QfOption',
    mixins: [LocaleMixin],
    componentName: 'QfOption',
    inject: ['select'],
    components: {
      QfCheckbox
    },
    props: {
      value: {
        required: true
      },
      label: [String, Number],
      created: Boolean,
      disabled: {
        type: Boolean,
        default: false
      }
    },
    data () {
      return {
        index: -1,
        groupDisabled: false,
        visible: true,
        hitState: false,
        hover: false
      };
    },
    computed: {
      isObject () {
        return Object.prototype.toString.call(this.value).toLowerCase() === '[object object]';
      },
      currentLabel () {
        return this.label || (this.isObject ? '' : this.value);
      },
      currentValue () {
        return this.value || this.label || '';
      },
      itemSelected () {
        if (!this.select.multiple) {
          return this.isEqual(this.value, this.select.value);
        } else {
          return this.contains(this.select.value, this.value);
        }
      },
      isMultiple () {
        return this.select.multiple;
      },
      limitReached () {
        if (this.select.multiple) {
          return !this.itemSelected &&
            (this.select.value || []).length >= this.select.multipleLimit &&
            this.select.multipleLimit > 0;
        } else {
          return false;
        }
      }
    },
    watch: {
      currentLabel () {
        this.select.setSelected();
      },
      value () {
        this.select.setSelected();
      }
    },
    methods: {
      isEqual (a, b) {
        if (!this.isObject) {
          return a === b;
        } else {
          const valueKey = this.select.valueKey;
          return ObjectUtil.getValueByPath(a, valueKey) === ObjectUtil.getValueByPath(b, valueKey);
        }
      },
      contains (arr = [], target) {
        if (!this.isObject) {
          return arr.indexOf(target) > -1;
        } else {
          const valueKey = this.select.valueKey;
          return arr.some(item => {
            return ObjectUtil.getValueByPath(item, valueKey) === ObjectUtil.getValueByPath(target, valueKey);
          });
        }
      },
      handleGroupDisabled (val) {
        this.groupDisabled = val;
      },
      hoverItem () {
        if (!this.disabled && !this.groupDisabled) {
          this.select.hoverIndex = this.select.options.indexOf(this);
        }
      },
      selectOptionClick () {
        if (this.disabled !== true && this.groupDisabled !== true) {
          this.select.$emit('optionClick', this);
        }
      },
      queryChange (query) {
        // query 里如果有正则中的特殊字符，需要先将这些字符转义
        let parsedQuery = String(query).replace(/(\^|\(|\)|\[|\]|\$|\*|\+|\.|\?|\\|\{|\}|\|)/g, '\\$1');
        this.visible = new RegExp(parsedQuery, 'i').test(this.currentLabel);
        if (!this.visible) {
          this.select.filteredOptionsCount--;
        }
      }
    },
    created () {
      this.select.options.push(this);
      this.select.cachedOptions.push(this);
      this.select.optionsCount++;
      this.select.filteredOptionsCount++;
      this.select.$on('queryChange', this.queryChange);
    },
    beforeDestroy () {
      this.select.onOptionDestroy(this.select.options.indexOf(this));
    }
  };
</script>
