<template>
  <HiveInput
    ref="inputElm"
    :class="className"
    :value="curValue"
    :placeholder="placeholder"
    v-bind="$attrs"
    v-on="listeners"
    @keydown="onKeyDown"
    @input="onInput"
  >
    <template v-slot:inputPrefixRaw>
      <HiveTag
        v-for="(tag, index) in tags"
        :key="index"
        closable
        @click="onTagClick(tag)"
        @close="onTagDelete(tag)"
      >
        {{ getTagText(tag) }}
      </HiveTag>
    </template>

    <template v-slot:inputSuffix>
      <span
        ref="inputMirrorElm"
        class="hive-input-tag__input-mirror"
      >{{ curValue }}</span>
    </template>

    <slot />
  </HiveInput>
</template>

<script>
import Input from './input';
import Tag from '../tag';

const name = 'hive-input-tag';

export default {
  name: name,
  components: {
    HiveInput: Input,
    HiveTag: Tag
  },
  props: {
    tags: { type: Array, default: () => [] },
    getTagKey: { type: Function, default: tag => tag },
    getTagText: { type: Function, default: tag => tag },
    value: { type: [Number, String], default: '' }
  },
  data() {
    return {
      curValue: this.$props.value
    };
  },
  computed: {
    className() {
      return [
        'hive-input-tag',
        {
          'hive-input-tag--empty': this.isEmpty
        }
      ];
    },
    isEmpty() {
      return !this.tags.length && !this.curValue;
    },
    listeners() {
      const {
        'tag-delete': tagDelete,
        'tag-click': tagClick,
        keydown,
        input,

        ...othersEvent
      } = this.$listeners;

      return { ...othersEvent };
    },
    hasSuffixIcon() {
      return this.$scopedSlots.suffixIcon || this.$attrs.suffixIcon;
    },
    placeholder() {
      return this.tags.length ? '' : this.$attrs.placeholder;
    }
  },
  watch: {
    value(v) {
      this.curValue = v;
    }
  },
  updated() {
    const padding = this.hasSuffixIcon ? 40 : 16;

    const { inputElm, inputMirrorElm } = this.$refs;

    if (inputElm && inputElm.$refs.refInputElem && inputMirrorElm) {
      if (this.$attrs.readonly && !this.curValue) {
        inputElm.$refs.refInputElem.style.width = '';
      } else if (this.tags.length && !this.curValue) {
        inputElm.$refs.refInputElem.style.width = `calc(0.75em + ${padding}px)`;
      } else if (!this.tags.length && !this.curValue) {
        inputElm.$refs.refInputElem.style.width = '100%';
      } else {
        inputElm.$refs.refInputElem.style.width = `${Math.ceil(inputMirrorElm.getBoundingClientRect().width) + 1 + padding}px`;
      }
    }
  },
  methods: {
    onInput(value) {
      this.curValue = value;
      this.$emit('input', value);
    },
    onKeyDown(e) {
      const { disabled } = this.$attrs;
      if (disabled) return;
      if (e.keyCode === 8 && this.curValue === '' && this.tags.length > 0) {
        this.onTagDelete(this.tags[this.tags.length - 1]);
      }
      this.$emit('keydown', e);
    },
    onTagClick(tag) {
      this.$emit('tag-click', tag);
    },
    onTagDelete(tagToDelete) {
      const tagsAfterDelete = this.tags.filter(tag => this.getTagKey(tag) !== this.getTagKey(tagToDelete));
      this.$emit('tag-delete', tagToDelete, tagsAfterDelete);
    }
  }
};
</script>
