<template>
  <div class="tag-editor control">
    <input ref="input" type="text" class="input" :value="tagText" @input="inputHandler" @focus="getFocus" @blur="loseFocus">
    <div class="tags">
      <span v-for="t in modelValue" :key="t" class="tag">{{t}}</span>
    </div>
  </div>
</template>

<script setup>

import {computed, nextTick, ref, useTemplateRef} from "vue";

const emit = defineEmits(["update:modelValue"]);

const props = defineProps({
  modelValue: {
    required: true,
    type: Array
  }
});

const hasFocus = ref(false);
const tagText = computed(() => props.modelValue.join(" "));
const inputElement = useTemplateRef("input");

function inputHandler(el) {
  let str = el.target.value;
  checkInput(str);
  nextTick(() => {
    el.target.value = str;
  });
}

function checkInput(str) {
  if (hasFocus.value) {
    const m = str.match(/\S\s+\S*$/);

    if (m !== null) {
      str = str.substring(0, m.index + 1);
    } else {
      str = "";
    }
  }

  const newTags = [...new Set(str.toString().split(/\s+/).filter(t => t.length > 0))];

  if (!arraysEqual(newTags, props.modelValue)) {
    emit("update:modelValue", newTags);
  }
}

function getFocus() {
  hasFocus.value = true;
}

function loseFocus() {
  hasFocus.value = false;
  checkInput(inputElement.value.value);
}

function arraysEqual(arr1, arr2) {
  if(arr1.length !== arr2.length)
    return false;
  for(let i = arr1.length; i--;) {
    if(arr1[i] !== arr2[i])
      return false;
  }

  return true;
}
</script>