<template>
  <div class="dynamic-tag-input" :class="{multiline: isMultiLine}" ref="dynamicTagInput" @focusout="stopFocus" @mouseleave="stopEditing">
    <schema-dynamic-field-dropdown
      v-if="dropdownOpened"
      :search-value="searchValue"
      :dynamic-tags="globalAndLocalDynamicTags"
      @select="selectDynamicValue"
      @close="toggleDropdown(false)"
    />
    <textarea
      v-if="type === 'textarea'"
      class="form-control"
      :value="value"
      :placeholder="schema.title"
      :required="!!schema.required"
      :readonly="!!schema.isReadOnly"
      @input="onInput"
      @click="startFocus"
      v-dynamic-tag-listener="toggleDropdown"
      v-bind="$attrs"
    />
    <input
      v-if="type === 'string'"
      :class="['form-control', 'form-control-' + schema.type]"
      :value="value"
      :placeholder="schema.title"
      :required="!!schema.required"
      :readonly="!!schema.isReadOnly"
      @input="onInput"
      @click="startFocus"
      v-dynamic-tag-listener="toggleDropdown"
      v-bind="$attrs"
    />
    <markdown
      v-if="type === 'markdown'"
      @input="onInput"
      @click="startFocus"
      :value="value"
      :required="!!schema.required"
      :readonly="!!schema.isReadOnly"
      :tags="globalAndLocalDynamicTags"
      v-dynamic-tag-listener="toggleDropdown"
      v-bind="$attrs"
    />
    <div
      v-if="!editing && type !== 'markdown'"
      class="dynamic-input form-control"
      :class="{placeholder: !hasValue, integer}"
      @mouseover="startEditing"
    >
      <p v-html="dynamicValue"></p>
    </div>
  </div>
</template>

<style lang="scss" scoped>
// This class is used by the dynamic-tag-parser to style tags explicitely
::v-deep .dynamic-tag {
  background-color: #eee;
  border: 1px solid #ccc;
  border-radius: 0.25rem;
  padding: 2px 6px;
  margin: 0 4px;
}

.dynamic-tag-input {
  height: 100%;
  position: relative;

  &:hover {
    cursor: text;
  }

  &:not(.multiline) {
    height: calc(1.5em + 0.75rem + 2px);

    .dynamic-input p {
      white-space: nowrap;
    }
  }

  .dynamic-input {
    overflow: hidden;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;

    &.placeholder p {
      color: #8e8e8e;
    }

    p {
      margin: 1px 0 0 0;
    }
  }

  // Replicate .form-control readonly & disabled states from Bootstrap
  .form-control[disabled] + .dynamic-input,
  .form-control[readonly] + .dynamic-input {
    background-color: #e9ecef;
    opacity: 1;
  }
}
</style>

<script>
import schemaDynamicFieldDropdown from '../schema/schema-dynamic-field-dropdown.vue';
import { DynamicTagListenerDirective } from './dynamic-tag-listener-directive';
import markdown from '../shared/form/markdown.vue';
import { parseDynamicTags } from '../tools/dynamic-tag-parser';

export default {
  inheritAttrs: false,
  name: 'dynamic-tag-input',
  directives: {
    'dynamic-tag-listener': DynamicTagListenerDirective
  },
  props: {
    type: {
      type: String,
      required: true
    },
    schema: {
      type: Object,
      required: true
    },
    preview: {
      type: String,
      required: false
    },
    value: {
      type: [String, Number],
      required: true
    },
    textarea: {
      type: Boolean,
      required: false
    }
  },
  data() {
    return {
      editing: false,
      dropdownOpened: false,
      integer: false,
      searchValue: '',
      focussed: false
    };
  },
  computed: {
    isMultiLine() {
      return this.type === 'textarea' || this.type === 'markdown'|| this.schema.format === 'markdown';
    },
    dynamicValue() {
      const parsedText = parseDynamicTags(this.value, this.globalAndLocalDynamicTags);

      return this.hasValue ? parsedText : this.preview;
    },
    globalAndLocalDynamicTags() {
      const localDynamicTags = (this.schema.dynamicValueTags || []);
      return [...localDynamicTags, ...this.globalTags];
    },
    hasValue() {
      return this.value !== undefined && this.value !== null && this.value !== '';
    },
    globalTags() {
      return this.$store.getters['data/getDynamicTags']();
    }
  },
  mounted() {
    this.integer = typeof this.value === 'number';
  },
  methods: {
    startEditing() {
      this.editing = true;
    },
    startFocus() {
      this.focussed = true;
    },
    stopFocus() {
      this.focussed = false;
      this.stopEditing();
    },
    stopEditing() {
      if(!this.focussed) {
        this.editing = false;
      }
    },
    selectDynamicValue(value) {
      const newValue = this.value.replace(/{{([a-zA-Z]*)(?![a-zA-Z]*}})/, `{{${value.text}}}`);
      this.$emit('input', newValue);

      this.editing = true;
    },
    toggleDropdown(opened, searchValue) {
      this.searchValue = searchValue;
      this.dropdownOpened = opened;
    },
    onInput(input) {
      const val = input.target ? input.target.value : input;
      this.$emit('input', val);
    }
  },
  components: {
    schemaDynamicFieldDropdown,
    markdown,
  }
};
</script>
