<template>
  <div class="documentation-editor" ref="documentationEditor" :class="{ editing }">
    <button class="btn" title="Documentatie openen" @click="open">
      <help-circle-outline-icon />
    </button>
    <modal ref="modal" @hide="handleUnsavedChanges">
      <div class="documentation-editor-controls p-3 d-flex justify-content-sm-between">
        <button :disabled="isLoading" :class="`btn documentation-editor-edit btn-${editing ? 'success' : 'secondary'}`" @click="editOrSave">
          {{ editText }}
        </button>
        <button class="btn btn-danger" @click="close">
          Sluit documentatie
        </button>
      </div>
      <div class="documentation-editor-content p-3 mb-3">
        <markdown :value="unsavedDocumentation.text" :min-rows="10" @input="onInput" ref="markdown"></markdown>
      </div>
    </modal>
    <confirm-dialog ref="dialog"></confirm-dialog>
  </div>
</template>

<script>
import { mapActions } from 'vuex';

import modal from './modal';
import markdown from './form/markdown';
import confirmDialog from './form/confirm-dialog';
import DocumentationApi from '../api/documentation-api';

const INITIAL_DOCUMENTATION = {
  text: ''
};

export default {
  props: {
    schema: {
      type: Object,
      required: true
    },
    small: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      editing: false,
      isLoading: false,
      documentation: INITIAL_DOCUMENTATION,
      unsavedDocumentation: INITIAL_DOCUMENTATION
    }
  },
  async mounted() {
    await this.fetchDocumentation();
  },
  methods: {
    ...mapActions('alerts', ['addError']),
    async fetchDocumentation() {
      try {
        this.isLoading = true;
        this.documentation = await DocumentationApi.getDocumentation(this.type);
        this.reset();
      } catch {
        await this.addError('Er is iets misgegaan bij het ophalen van de documentatie.');
      } finally {
        this.isLoading = false;
      }
    },
    async saveDocumentation() {
      try {
        this.isLoading = true;
        this.documentation = await DocumentationApi.saveDocumentation(this.type, this.unsavedDocumentation);
        this.reset();
      } catch {
        await this.addError('Er is iets misgegaan bij het opslaan van de documentatie.');
      } finally {
        this.isLoading = false;
      }
    },
    open() {
      this.$refs.modal.show();

      if (!this.documentation.text) {
        this.focusMarkdown();
      }
    },
    async close() {
      await this.handleUnsavedChanges();
      this.$refs.modal.hide();
    },
    async handleUnsavedChanges() {
      if (this.hasUnsavedChanges) {
        try {
          await this.$refs.dialog.confirm(
            'Wijzigingen',
            `Er zijn niet-opgeslagen wijzigingen in de documentatie, wil je die opslaan?`,
            'Ja, opslaan',
            'Nee'
          );
          await this.saveDocumentation();
        } catch (error) {
          this.reset();
        }
      }
      this.editing = false;
    },
    reset() {
      this.unsavedDocumentation = { ...this.documentation };
    },
    async editOrSave() {
      if (this.editing) {
        if (this.hasUnsavedChanges) {
          await this.saveDocumentation();
        }
        this.editing = false;
      } else {
        this.editing = true;
        this.focusMarkdown();
      }
    },
    onInput(value) {
      this.unsavedDocumentation.text = value;
    },
    async focusMarkdown() {
      this.editing = true;

      await this.$nextTick();
      this.$refs.markdown.$refs.textarea.focus();
    }
  },
  computed: {
    type() {
      return this.schema.properties.$type.enum[0];
    },
    hasUnsavedChanges() {
      return this.unsavedDocumentation.text !== this.documentation.text;
    },
    editText() {
      return this.hasUnsavedChanges || this.editing ? 'Opslaan' : 'Wijzig';
    }
  },
  components: {
    markdown,
    confirmDialog,
    modal
  }
}
</script>

<style lang="scss" scoped>
.documentation-editor {
  &-controls {
    background-color: #f5f5f5;
    border-radius: .3rem .3rem 0 0;
    border-bottom: 1px solid rgba(0, 0, 0, .125);
  }

  &-content {
    height: 100%;
    overflow-y: scroll;
  }

  ::v-deep .modal-content {
    width: 60vw;
    height: 80vh;
  }

  &:not(.editing) {
    ::v-deep .markdown-component {
      pointer-events: none;
    }

    ::v-deep .wmd-preview {
      background: none;
      border: none;

      &:not(:empty) {
        padding: 0;
      }
    }
  }
}
</style>
