<template>
  <section>
    <b-modal :active="isShownDatasetEditor" :on-cancel="hideDatasetEditor" :width="1200">
      <div class="card">
        <div class="card-content">
          <b-field
            label="Edit dataset in JSON format"
            :type="inputMessageType"
          >
            <b-input v-model="data" size="is-small" type="textarea" @input="onInput()" :custom-class="inputMessage != '' ? 'shorter' : ''"></b-input>
          </b-field>

          <transition name="fade">
            <b-message v-if="inputMessage != ''" type="is-danger">
              {{ inputMessage }}
            </b-message>
          </transition>

          <div class="buttons">
            <b-button type="is-danger" outlined @click="close()">Close</b-button>
            <b-button
              v-if="hasDataChanged || wasInputModified"
              type="is-primary"
              outlined
              @click="reload()"
              >Reset</b-button
            >
            <b-button type="is-primary" :disabled="hasError" @click="setData()">Save</b-button>
            <span v-if="wasInputModified">Modified.&nbsp;</span>
            <span v-if="hasDataChanged && !wasInputModified">Dataset changed in background.</span>
          </div>
        </div>
      </div>
    </b-modal>
  </section>
</template>

<script>
import { mapGetters, mapActions, mapMutations } from 'vuex'
import { isEqual } from 'lodash'
import { validateDataset } from '@/store/modules/data.store.js'

const JSON5 = require('json5')

export default {
  name: 'DatasetEditorModal',
  
  data() {
    return {
      data: '{ "nodes": [], "links": [] }',
      inputMessageType: '',
      inputMessage: '',
      wasInputModified: false
    }
  },
  computed: {
    ...mapGetters('interaction', ['isShownDatasetEditor']),
    ...mapGetters('data', ['getState']),
    hasDataChanged() {
      try {
        return !isEqual(JSON5.parse(this.data), this.getState)
      } catch {
        return false
      }
    },
    hasError() {
      return this.inputMessage !== ''
    }
  },

  mounted() {
    // reload data from store when opening modal
    this.$store.subscribeAction(action => {
      if (action.type === 'interaction/showDatasetEditor') this.reload()
    })
  },

  methods: {
    ...mapActions('interaction', ['hideDatasetEditor']),
    ...mapMutations('data', ['INIT']),
    setData() {
      this.resetError()

      let parsedData = null
      try {
        parsedData = JSON5.parse(this.data)
        validateDataset(parsedData)
      } catch (e) {
        this.inputMessage = e.toString()
        this.inputMessageType = 'is-danger'
        return
      }

      this.$store.dispatch('data/import', parsedData)
      this.hideDatasetEditor()
      this.reload()
    },

    reload() {
      this.wasInputModified = false
      this.data = JSON5.stringify(this.getState, null, '\t')
    },

    onInput() {
      this.wasInputModified = true
      try {
        validateDataset(JSON5.parse(this.data))
      } catch (e) {
        this.inputMessage = e.toString()
        this.inputMessageType = 'is-danger'
        return
      }
      this.resetError()
    },

    close() {
      this.hideDatasetEditor()
      this.resetError()
      this.reload()
    },

    resetError() {
      this.inputMessageType = ''
      this.inputMessage = ''
    }
  }
}
</script>

<style lang="sass">
.textarea
  max-height: 85vh !important
  min-height: 70vh !important

.textarea .shorter 
  max-height: 50vh !important
</style>
