<template>
  <section>
    <b-modal :active="show" :on-cancel="close" :width="1200" destroy-on-hide>
      <div class="card">
        <div class="card-content">
          <h1 class="title">
            Dataset editor
          </h1>

          <div class="columns">
            <div class="column">
              <section id="dataset-selection">
                <h2 class="title is-6">
                  Select predefined dataset:
                </h2>
                <b-field grouped group-multiline>
                  <div
                    v-for="dataset in datasets"
                    :key="dataset.name"
                    class="control"
                    @click="selectDataset(dataset)"
                  >
                    <b-taglist attached>
                      <b-tag type="is-dark" class="tag-name">
                        {{ dataset.name }}
                      </b-tag>
                      <b-tag type="is-info">
                        {{ dataset.data.nodes.length }} /
                        {{ dataset.data.links.length }}
                      </b-tag>
                    </b-taglist>
                  </div>
                </b-field>
              </section>
            </div>

            <div class="column is-four-fifths">
              <section id="dataset-editor-textarea">
                <h2 class="title is-6">
                  Edit current dataset in JSON5:
                </h2>
                <b-field :type="inputMessageType">
                  <b-input
                    v-model="data"
                    size="is-small"
                    type="textarea"
                    :custom-class="inputMessage !== '' ? 'shorter' : ''"
                    @input="onInput()"
                  />
                </b-field>

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

          <div class="columns">
            <div class="column">
              <section 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
                >
              </section>
            </div>
          </div>
        </div>
      </div>
    </b-modal>
  </section>
</template>

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

const JSON5 = require('json5')

export default {
  name: 'DatasetEditorModal',

  props: {
    instanceId: { type: Number, required: true },
    show: { type: Boolean, required: true }
  },

  data() {
    return {
      data: '{ "nodes": [], "links": [] }',
      inputMessageType: '',
      inputMessage: '',
      wasInputModified: false,
      generateNodeNum: 0,
      generateLinkNum: 0
    }
  },

  computed: {
    hasDataChanged() {
      try {
        return !isEqual(JSON5.parse(this.data), this.getCurrentState())
      } catch (e) {
        return false
      }
    },
    hasError() {
      return this.inputMessage !== ''
    },
    datasets() {
      return this.$datasets
    }
  },

  mounted() {
    this.reload()
  },

  methods: {
    ...mapActions('data', { _import: 'import' }),
    ...mapGetters('data', ['getState']),

    getCurrentState() {
      return this.getState()(this.instanceId)
    },

    import(data) {
      this._import({
        slotId: this.instanceId,
        state: { nodes: data.nodes, links: data.links, tags: [] }
      })
    },

    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.import(parsedData)
      this.$emit('hide')
      this.reload()
    },

    reload() {
      this.wasInputModified = false
      this.data = JSON5.stringify(this.getCurrentState(), 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.$emit('hide')
      this.resetError()
      this.reload()
    },

    resetError() {
      this.inputMessageType = ''
      this.inputMessage = ''
    },

    selectDataset(ds) {
      console.log('Selected dataset: ' + JSON.stringify(ds))
      this.import(ds.data)
      this.close()
    }
  }
}
</script>

<style lang="sass" scoped>
.card
  min-height: 100%
  height: 100%

section
  margin-bottom: 2.5em
  h2.title.is-6
    margin-bottom: 1rem

.tag
  cursor: pointer
  &.tag-name
    width: 10em
    text-align: left
    justify-content: left

label.label
  font-size: 0.8rem
  margin-bottom: 0.2em
</style>

<style lang="sass">
#dataset-editor-textarea textarea
  max-height: 70vh
  min-height: 70vh

#dataset-editor-textarea textarea.shorter
  max-height: 60vh
  min-height: 60vh
</style>
