<template>
  <label :for="name" class="textarea-input" :class="[inputClass, { 'textarea-input--error': hasErrors } ]">
    <span class="textarea-input__label" v-if="label" v-text="label"></span>
    <div class="textarea-input__wrapper">
      <div
        class="textarea-input__textarea"
        :class="{
          'has-content': hasContent
        }"
        contenteditable="true"
        tabindex="0"
        :data-text="inputPlaceholder"
        @input="$emit('input', $event.target.innerText), resize()"
        @paste.stop.prevent="onPaste($event)"
        @blur="resetErrors"
        ref="textArea"
      ></div>
      <transition name="fade">
        <img v-if="hasErrors" :src="errorImg" alt="error" class="textarea-input__image">
      </transition>
    </div>
    <transition name="fade">
      <template v-if="hasErrors">
        <p
          class="textarea-input__message textarea-input__message--error"
          role="alert"
          v-for="(message, index) in errors"
          :key="index"
          v-text="message"
        ></p>
      </template>
    </transition>
  </label>
</template>

<script>
import size from 'lodash/size';
import { TweenLite } from 'gsap/TweenMax'

export default {
  name: 'textarea-input',
  props: {
    name: {
      type: String,
      required: true,
    },
    inputStyle: {
      type: String,
      required: false,
      default: 'boxed',
    },
    label: {
      type: String,
      required: false,
    },
    value: {
      type: [Number, String],
      required: true,
    },
    placeholder: {
      type: String,
      required: false,
    },
    required: {
      type: Boolean,
      required: false,
      default: false,
    },
    errors: {
      type: Array,
      required: false,
    },
    errorImg: {
      type: String,
      required: false,
    },
  },
  data() {
    return {
      textAreaHeight: null,
    }
  },
  computed: {
    hasContent () {
      return size(this.value) > 0
    },
    hasErrors() {
      return size(this.errors) > 0;
    },
    inputClass() {
      return this.inputStyle === 'boxed' ? 'textarea-input--boxed' : 'textarea-input--line';
    },
    inputPlaceholder() {
      return this.placeholder ? this.placeholder : '';
    }
  },
  watch: {
    value() {
      if (!this.hasContent) {
        const { textArea } = this.$refs;
        TweenLite.to(textArea, 0.3, { minHeight: this.textAreaHeight });
      }
    }
  },
  mounted() {
    this.getInitialHeight();
  },
  methods: {
    resetErrors() {
      this.$emit('reset-errors', this.name)
    },
    getInitialHeight() {
      const { textArea } = this.$refs
      const OH = textArea.offsetHeight
      this.textAreaHeight = OH;
    },
    onPaste (e) {
      let paste = (e.clipboardData || window.clipBoardData).getData('text/plain');
      document.execCommand('inserttext', false, paste);
    },
    resize () {
      const { textArea } = this.$refs;
      const OH = textArea.offsetHeight;
      const CH = textArea.clientHeight;
      const OFFSET = OH - CH;
      TweenLite.to(textArea, 0.3, { minHeight: (textArea.scrollHeight + OFFSET) })
    },
  }
}
</script>

<style lang="scss" scoped>
.textarea-input {
  display: flex;
  flex-direction: column;
  position: relative;
  margin-bottom: 30px;
  margin-bottom: 3rem;
  &__label {
    @include body-small(medium, label, $color-black-primary, tertiary, quaternary);
    margin-bottom: 5px;
    margin-bottom: .5rem;
    transition: color transition(fast);
  }
  &__wrapper {
    position: relative;
  }
  &__image {
    position: absolute;
    top: 15px;
    right: 15px;
  }
  &__textarea {
    position: relative;
    min-height: 90px;
    width: 100%;
    background-color: transparent;
    outline: none;
    caret-color: $color-primary;
    padding: 10px 10px;
    padding: 1rem 1rem;
    cursor: text;
    transition: all transition(fast);
    @include body-normal(regular, placeholder, $color-black-primary, tertiary, quaternary);
    &:after {
      display: block;
      opacity: 1;
      content: attr(data-text);
      text-align: left;
      position: absolute;
      top: 10px;
      left: 10px;
      @include body-normal(regular, placeholder, $color-black-primary, tertiary, quaternary);
      color: rgba($color-black-primary, .5);
    }
    &.has-content {
      &:after {
        opacity: 0;
      }
    }
  }
  &__message {
    position: absolute;
    margin-bottom: 0;
    left: 0;
    bottom: -30px;
    bottom: -3rem;
    @include body-small;
    &--error {
      color: $color-message-tertiary;
    }
  }
  &--boxed {
    .textarea-input__textarea {
      background-color: $white;
      border-radius: border-radius(primary);
      box-shadow: box-shadow(secondary);
      border-bottom: 2px solid $white;
      &:focus {
        border-bottom-color: $color-primary;
      }
    }
  }
  &--line {
    .textarea-input__textarea {
      border-bottom: border(solid-secondary);
      &:focus {
        border-bottom-color: $color-primary;
      }
    }
    .textarea-input__message {
      left: 10px;
      left: 1rem;
    }
  }
  &--error {
    .textarea-input__label {
      color: $color-message-tertiary;
    }
    .textarea-input__textarea {
      outline: none;
      border-bottom-color: $color-message-tertiary;
    }
  }
}
</style>
