<template>
  <div class="player">
    <or-button
      color="primary"
      type="secondary"
      :loading="loading"
      :disabled="disable"
      @click="parseSsmlCodeForGenerateAudio"
    >
      Preview audio
    </or-button>

    <audio
      v-if="audioUrl !== ''"
      ref="audioPlayer"
      controls
      :src="audioUrl"
    />
  </div>
</template>

<script>
import _ from 'lodash';
import api from '../../../utils/api.js';
import JSON2XML from '../../../utils/JSON2XML.js';
import filterDependentAttributes from '../../../utils/filterDependentAttributes.js';
import { removeNewLinesFromString, validateMergeFields } from '../../../utils/string-helpers.js';

export default {
  name: 'Player',

  props: {
    ssml: { type: String, default: '' },
    mode: { type: String, default: 'visualEditor' }
  },

  data () {
    return {
      loading: false,
      audioUrl: ''
    };
  },

  computed: {
    env () { return this.$liteStore.get('env/env'); },
    visualEditorContent () { return this.$liteStore.get('editable/editableTmpContent'); },

    /* eslint-disable */
    disable () {
      
      if (this.$liteStore.get('app/readonly')) return true;

      if (this.mode === 'visualEditor') return _.isEmpty(this.visualEditorContent);
      if (this.mode === 'codeEditor') return this.ssml === '';x
    }
    /* eslint-enable */
  },

  created () {
    this.$EventBus.$on('merge-fields::replaced', replacedSsml => this.generateAudio(replacedSsml));
    this.$EventBus.$on('modal-close', this.resetPlayer);
  },

  beforeDestroy () {
    this.resetPlayer();
  },

  methods: {
    parseSsmlCodeForGenerateAudio () {
      setTimeout(() => this.checkSsmlCodeForMergeFieldUse(), 10);
    },

    resetPlayer () {
      if (this.$refs['audioPlayer']) this.$refs['audioPlayer'].pause();
      this.audioUrl = '';
      this.loading = false;
    },

    checkSsmlCodeForMergeFieldUse () {
      let mergeFieldInUse = false;
      const tagsConfig = this.$liteStore.get('tagList/getTagsList');

      if (this.mode === 'visualEditor') mergeFieldInUse = validateMergeFields(JSON2XML(filterDependentAttributes(this.visualEditorContent, tagsConfig)));
      if (this.mode === 'codeEditor') mergeFieldInUse = validateMergeFields(this.ssml);

      if (mergeFieldInUse) {
        this.$EventBus.$emit('merge-fields::replace');
        return;
      }

      if (this.mode === 'visualEditor') this.ssml = JSON2XML(filterDependentAttributes(this.visualEditorContent, tagsConfig));
      this.generateAudio(this.ssml);
    },

    async generateAudio (ssml) {
      this.loading = true;
      this.audioUrl = '';
      
      try {
        const data = await this.generateAudioFromSsml(ssml);
        if (this.loading) this.audioUrl = _.get(data, 'audioUrl', '');
      } catch (error) {
        if (error.name === 'TypeError') {
          console.error(error);
        } else {
          console.log('GOT ERROR', error);
          const message = this.parseError(error);
          
          
          this.$EventBus.$emit('notify', {
            type: 'error',
            message: message
          });
        }
      } finally {
        this.loading = false;
      }
    },

    parseError (error) {
      if (error.body) {
        return error.body.error
          ? _.get(error.body.error, 'message', 'Something went wrong.')
          : _.get(error.body, 'message', 'Something went wrong.');
      }

      if (error.error) {
        return error.error.message
          ? _.get(error.error, 'message', 'Something went wrong.')
          : _.get(error, 'message', 'Something went wrong.');
      }

      if (error.message) return error.message;
      
      return 'Something went wrong.';
    },

    generateAudioFromSsml (ssml) {
      const params = {
        ssml: removeNewLinesFromString(ssml),
        language: this.$liteStore.get('app/language'),
        provider: this.$liteStore.get('app/provider'),
        engine: this.$liteStore.get('app/engine'),
        gender: this.$liteStore.get('app/gender'),
        voice: this.$liteStore.get('app/voice')
      };

      return api.post(
        `${this.env.sdkApiUrl}/http/${this.env.providersAccountId}/synthesize-speech`,
        params,
        { headers: { Authorization: `USER ${this.env.token}` } }
      )
        .then(response => response.data.error ? Promise.reject(response.data.error) : Promise.resolve(response.data))
        .catch(error => Promise.reject(error));
    }
  }
};
</script>

<style lang="scss" scoped>
.player {
  display: flex;
  flex-wrap: wrap;
}

.ui-button {
  // margin-left: auto;
}

audio {
  display: block;
  flex-basis: 100%;
  margin-top: 1rem;
}
</style>
