<template>
  <form @submit.prevent>
    <h2 class="metadata-title">
      Metadata
    </h2>
    <ui-textbox
      v-model.trim="name"
      class="form-element"
      floating-label
      label="Name"
      @blur="$emit('saveReferenceName', name)"
      @keydown="handleReferenceRestrictions"
    />
    <ui-select
      v-model="assetMetadata.assetType"
      class="form-element"
      floating-label
      disable-filter
      label="Asset Type"
      :options="assetTypes"
      @select="saveAssetMeta('assetType')"
    />
    <ui-textbox
      v-model.trim="assetMetadata.credit"
      class="form-element"
      floating-label
      label="Credit"
      @blur="saveAssetMeta('credit')"
    />
    <ui-textbox
      v-model.trim="assetMetadata.creditUrl"
      class="form-element"
      floating-label
      label="Credit URL"
      @blur="saveAssetMeta('creditUrl')"
    />
    <ui-textbox
      v-model.trim="assetMetadata.copyright"
      class="form-element"
      floating-label
      label="Source"
      @blur="saveAssetMeta('copyright')"
    />
    <ui-textbox
      ref="caption"
      v-model.trim="assetMetadata.caption"
      class="form-element"
      :multi-line="true"
      label="Caption"
      floating-label
      :autosize="true"
      :rows="1"
      @blur="saveAssetMeta('caption')"
    />
    <ui-textbox
      v-model.trim="assetMetadata.altText"
      class="form-element"
      floating-label
      label="Alt text"
      @blur="saveAssetMeta('altText')"
    />
    <collection-slug
      edit-mode
      :value="assetMetadata.collectionSlug"
      @fieldChange="saveField"
    />
    <tags
      :provided-tags="tags"
      :selected-tags="assetMetadata.tags"
      :validation="validations.tags"
      placeholder="Select from list"
      @selectTags="saveArray($event, 'tags')"
    />
    <keywords
      label="Keywords"
      :items="assetMetadata.keywords"
      @saveKeywords="saveArray($event, 'keywords')"
    />
  </form>
</template>
<script>

import { ALPHANUMERIC_RE, HIDDEN_CHARS_RE } from 'Config/constants';
import CollectionSlug from './CollectionSlug.vue';
import Keywords from './Keywords.vue';
import Tags from './Tags.vue';

const { UiSelect, UiTextbox } = window.kiln.utils.components,
  ARRAY_PROPERTIES = ['tags', 'keywords'];

export default {
  components: {
    CollectionSlug,
    Keywords,
    Tags,
    UiSelect,
    UiTextbox
  },
  props: {
    assetId: {
      type: String,
      required: true
    },
    referenceName: {
      type: String,
      required: true,
      default: ''
    },
    metadata: {
      type: Object,
      default: () => ({})
    },
    tags: {
      type: Object,
      default: () => ({})
    },
    assetTypes: {
      type: Array,
      default: () => []
    },
    validations: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      name: '',
      assetMetadata: {
        altText: '',
        caption: '',
        credit: '',
        creditUrl: '',
        copyright: '',
        assetType: '',
        collectionSlug: '',
        keywords: [],
        tags: []
      }
    };
  },
  watch: {
    name(val) {
      this.name = val.replace(ALPHANUMERIC_RE, '');
    }
  },
  mounted() {
    this.assetMetadata = Object.keys(this.assetMetadata).reduce((accum, prop) => ({
      ...accum,
      [prop]: ARRAY_PROPERTIES.includes(prop) ? [...this.metadata[prop]] : this.metadata[prop]
    }), {});

    // refresh caption textbox's size
    this.$nextTick(() => {
      this.$refs.caption.refreshSize();
    });

    this.name = this.referenceName;
  },
  methods: {
    /**
     * Handles text input restrictions for Reference name
     * @param {Object} event Input event
     */
    handleReferenceRestrictions(event) {
      if (event.key.match(ALPHANUMERIC_RE)) {
        event.preventDefault();
      }
    },
    /**
     * Saves specific local data to DB
     * @param {string} metadataItem Metadata inside asset that will be saved
     */
    saveAssetMeta(metadataItem = '') {
      if (metadataItem) {
        let newData = this.assetMetadata[metadataItem];

        if (!ARRAY_PROPERTIES.includes(metadataItem) && typeof newData === 'string') {
          newData = newData.replace(HIDDEN_CHARS_RE, '').trim();
          this.assetMetadata[metadataItem] = newData;
        }

        if (newData !== this.metadata[metadataItem]) {
          this.$emit(
            'saveAssetMeta',
            metadataItem,
            ARRAY_PROPERTIES.includes(metadataItem) ? [...newData] : newData
          );
        }
      }
    },
    /**
     * Saves general metadata fields into data
     * @param {string} metaField
     * @param {string} metaValue
     */
    saveField(metaField, metaValue) {
      this.assetMetadata[metaField] = metaValue;
      this.saveAssetMeta(metaField);
    },
    /**
     * Saves new array into the corresponding data field
     * @param {string[]} newArray
     * @param {string} field
     */
    saveArray(newArray = [], field = '') {
      if (field) {
        const newValues = newArray.reduce((accum, item) => accum.concat(item), ''),
          oldValues = this.metadata[field].reduce((accum, item) => accum.concat(item), '');

        if (newValues !== oldValues) {
          this.assetMetadata[field] = newArray;
          this.saveAssetMeta(field);
        }
      }
    }
  }
};
</script>
<style lang="scss" scoped>
  @import 'Styles/fonts.scss';
  @import 'Styles/helpers.scss';

  .metadata-title {
    @extend .metadata-title;

    color: $border-color-darker;
    margin: 2px 0 10px;
  }

  form {
    align-items: flex-start;
    display: flex;
    flex-flow: column;
    width: 320px;

    .metadata-form {
      width: 100%;
    }

    .form-element {
      padding: 8px 0;
      width: 100%;
    }

    /deep/ {
      .ui-textbox.has-floating-label .ui-textbox__label-text.is-inline {
        transform: translateY(1.625rem) scale(1);
      }

      .ui-textbox__label-text,
      .ui-textbox__input,
      .ui-textbox__textarea {
        font-size: $standard-font-size;
      }

      .ui-textbox__textarea {
        padding: 6px 0 5px;
      }

      .ui-textbox.has-floating-label .ui-textbox__label-text.is-floating {
        font-size: $small-font-size;
      }

      .ui-select {
        @extend .select-input-style;
      }
    }
  }
</style>
