<template>
  <loader>
    <div v-if="!$route.meta.store.state.fetchItemsError">
      <header class="page-header pt-4 pb-3">
        <h1>{{capitalizedItemName}} Editor</h1>

        <div class="page-header-buttons">
          <references ref="refsDialog" v-if="item && !isNew" :item-id="item.id" :item-name="this.capitalizedItemName"></references>
        </div>
      </header>

      <validator-group>
        <editor :item="item" :schema="$route.meta.store.schema"></editor>

        <bottom-toolbar>
          <button class="btn btn-danger mr-2" @click="del" v-if="!isNew" :disabled="preventDelete">
            <span class="icon-cross"></span>
            Verwijderen
          </button>

          <!-- if singletonpage, refresh page -->
          <button v-if="preventDelete" slot="right" type="button" class="btn btn-secondary mr-2" @click="refreshThisPage">Annuleren</button>
          <!-- else go back to  overview page of all crud items -->
          <router-link slot="right" :to="{ name: 'index-' + $route.meta.itemName, activeClass: 'hidden', query: $route.query }" class="btn btn-secondary mr-2" v-else>Annuleren</router-link>

          <button class="btn btn-primary mr-2" slot="right" v-if="!isNew && !isSingleton && !preventUpdate && !preventCopy" @click="createCopy">
            <span class="icon-copy"></span>
            Kopieer {{capitalizedItemName}}
          </button>

          <submit slot="right" :action="save" :disabled="preventUpdate">
            <span class="icon-floppy-disk"></span>
            Opslaan
          </submit>
        </bottom-toolbar>
        <confirm-dialog ref="dialog"></confirm-dialog>
      </validator-group>
    </div>
  </loader>
</template>

<style lang="scss" scoped>
  .hidden {
    display: none;
  }
</style>

<script>
  import { permissionStore } from '../tools/permission-store.js'
  import editor from '../shared/editor.vue';
  import loader from '../shared/loader.vue';
  import references from '../shared/references.vue';
  import * as formElements from '../shared/form/all.js';

  export default {
    name: 'crud-editor',
    data() {
      return {
        item: null,
        isLoading: true
      };
    },
    computed: {
      isNew() {
        return !this.item || !this.item.id;
      },
      capitalizedItemName() {
        return this.$route.meta.store.schema.title || this.$route.meta.itemName.replace(/\b\w/g, c => c.toUpperCase());
      },
      preventCopy() {
        return this.$route.meta.store.schema.preventCopy;
      },
      preventUpdate() {
        return !permissionStore.canUpdate(this.$route.meta.itemName);
      },
      preventDelete() {
        return this.$route.meta.store.schema.preventDelete || !permissionStore.canDelete(this.$route.meta.itemName);
      },
      isSingleton() {
        return !!this.$route.meta.store.schema.isSingleton;
      }
    },
    mounted() {
      if (this.$route.meta.store.state.fetchItemsError) {
        this.$store.dispatch('alerts/addError', this.$route.meta.store.state.fetchItemsError);
      }
    },
    methods: {
      save() {
        this.$route.meta.store.upsert(this.item)
          .then(item => {
            // navigate from /create to new created item, so the page can be refreshed.
            // note: a singletonitem has only 1 url
            if (this.isNew && !this.isSingleton) {
              this.$router.replace({
                name: this.$route.meta.itemName + '-editor',
                params: { id: item.id },
                query: this.$route.query
              });
            }

            this.item = item;
            this.$store.dispatch('alerts/addSuccess', 'Opgeslagen');
          })
          .catch(e => this.$store.dispatch('alerts/addError', `Opslaan is niet gelukt! <br> ${e.message}`));
      },
      del() {
        this.$refs.dialog.confirm(
          this.capitalizedItemName + ' verwijderen',
          `Weet je zeker dat je deze ${this.$route.meta.itemName} wilt verwijderen?`
        )
        .then(() => {
          this.$route.meta.store.delete(this.item)
            .then(() => {
              this.$router.push({ name: 'index-' + this.$route.meta.itemName, query: this.$route.query });
              this.$store.dispatch('alerts/addSuccess', 'Verwijderd');
            })
            .catch(error => {
              if (error.isReferenceError) {
                this.$refs.refsDialog.openErrorModal();
              }
              this.$store.dispatch('alerts/addError', `Verwijderen is niet gelukt! <br> ${error.message}`);

              throw error;
            })
        },
        () => {
          // intentionally empty for removing console error when dismissing dialog
        });
      },
      refreshThisPage() {
        window.location.reload();
      },
      createCopy() {
        const copyParams = {id: this.item.id, isCopied: true};

        this.$store.dispatch('alerts/addSuccess', 'Kopie gemaakt');
        this.$router.push({
          name: 'create-' + this.$route.meta.itemName,
          params: copyParams
        });
      }
    },
    beforeRouteEnter(to, from, next) {
      var promise = to.params.id
        ? to.meta.store.getItemById(to.params.id)
        : Promise.resolve(
          to.meta.newItem instanceof Function
            ? to.meta.newItem(to.query)
            : to.meta.newItem[to.query.type](to.query)
        );
      return promise.then(item => {
        // delete id to make save as new item possible
        if (to.params.isCopied) {
          delete item.id;
        }
        next(vm => {
          vm.item = item,
          vm.isLoading = false
        });
      });
    },
    components: {
      editor,
      loader,
      references,
      ...formElements
    }
  }
</script>
