<template>
  <loader>
    <validator-group>
      <div class="create-new-page m-auto col-lg-6">
        <div class="card">
          <div class="card-body">
            <div class="row">
              <h1 class="col-sm-12 mb-4">Nieuwe pagina aanmaken</h1>
            </div>
            <div class="row">
              <div class="col-sm-12">
                <field label="Bovenliggende pagina" class="col-sm-12">
                  <page-picker v-model="parentId"></page-picker>
                  <validator :test="!!parentId">Kies een pagina uit de lijst</validator>
                </field>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-12">
                <field label="Titel" class="col-sm-12">
                  <input class="form-control" v-model="title" required />
                  <validator :test="isValidTitle">{{ invalidTitleMessage }}</validator>
                </field>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-12">
                <field label="Type" class="col-sm-12" :class="{ 'no-page-type': !pageTypeId }">
                  <select class="form-control" :value="pageTypeId" @change="changePageTypeId">
                    <option value="">Kies paginatype</option>
                    <optgroup label="Onbeperkt aanmaken">
                      <option
                        v-for="type in orderedAndFilteredTypes.filter((type) => !type.isSingleton)"
                        :key="type.title"
                        :value="getPageTypeId(type)"
                      >
                        {{ type.title }}
                      </option>
                    </optgroup>

                    <optgroup label="Maximaal 1 van aanmaken">
                      <option
                        v-for="type in orderedAndFilteredTypes.filter((type) => type.isSingleton)"
                        :key="type.title"
                        :value="getPageTypeId(type)"
                      >
                        {{ type.title }}
                      </option>
                    </optgroup>
                  </select>
                  <validator :test="!!pageTypeId"></validator>
                </field>
              </div>
            </div>
            <div class="row">
              <div class="col-sm-12" v-if="showLanguageElements">
                <field label="Taal" class="form-group col-sm-12">
                  <language-picker :languageInfos="languageInfos" :translations="translations" v-model="language" />
                </field>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div v-if="version && !isFolder" class="m-auto col-lg-6">
        <hr />
        <version-editor :version="version" :state="{}" :isNew="true" ref="version-editor" :permissions="permissions" />
      </div>
      <confirm-dialog ref="dialog"></confirm-dialog>
      <bottom-toolbar>
        <submit slot="right" :action="save" button-class="btn text-left btn-success">
          <span class="icon-floppy-disk"></span>
          Opslaan
        </submit>
      </bottom-toolbar>
    </validator-group>
  </loader>
</template>

<script lang="ts">
import _orderBy from 'lodash/orderBy';
import slugify from 'slugify';
import { Component, Ref, Vue, Watch } from 'vue-property-decorator';
import { Route } from 'vue-router';
import { namespace, State } from 'vuex-class';
import { initialValue } from '../schema/schema-scripts';
import formElements from '../shared/form/all';
import BottomToolbar from '../shared/form/bottom-toolbar.vue';
import languagePicker from '../shared/form/language-picker.vue';
import PagePicker from '../shared/form/page-picker.vue';
import loader from '../shared/loader.vue';
import { LanguageInfo, Translation } from '../stores/types/TranslationStoreModel';
import { NamedSchemaItems, Schema, SchemaItem, Version } from '../types/api';
import VersionEditor from './version-editor.vue';

const AlertStore = namespace('alerts');
const PageStore = namespace('pages');
const PermissionStore = namespace('permissions');

export interface pageType {
  properties: {
    $type: {
      enum: string[];
    };
  };
}

@Component({
  components: {
    loader,
    languagePicker,
    BottomToolbar,
    PagePicker,
    VersionEditor,
    ...formElements
  },
  beforeRouteEnter(to: Route, from: Route, next: (to?: ((vm: CreatePage) => any) | void) => void): void {
    next((vm) => {
      vm.isLoading = false;
    });
  },
  beforeRouteLeave(to, from, next) {
    if (this.$refs['version-editor'] && (this.$refs['version-editor'] as any).changed) {
      (this.$refs.dialog as any)
        .confirm('De nieuwe pagina is nog niet opgeslagen', 'Weet je zeker dat je door wilt gaan?', 'Ja, doorgaan', 'Terug')
        .then(() => {
          next();
        });
    } else {
      next();
    }
  }
})
export default class CreatePage extends Vue {
  pageTypeId = '';

  isLoading = true;

  translations = [] as Translation[];

  parentId: string | null = null;

  title = '';

  language: string | null = null;

  version: Version | null = null;

  titleMinLength = 2;

  @State((state) => state.translations.languageInfos)
  readonly languageInfos!: LanguageInfo[];

  @State((state) => state.translations.isLoadingLanguageInfos)
  readonly isLoadingLanguageInfos!: boolean;

  @State((state) => state.pages.schema)
  readonly schema!: Schema;

  @AlertStore.Action('addCmsError') readonly addCmsError!: Function;

  @Ref('version-editor') readonly versionEditor!: VersionEditor;

  @PageStore.Getter('types') readonly types!: NamedSchemaItems;
  @PageStore.Action('create') readonly createPage!: Function;
  @PermissionStore.Getter('getPermissions') readonly getPermissions!: Function;

  mounted() {
    this.parentId = this.$router.currentRoute.params.parentId ? this.$router.currentRoute.params.parentId : null;
  }

  getPageTypeId(type: SchemaItem): string {
    if (!type.properties.$type.enum) return '';
    return type.properties.$type.enum[0];
  }

  changePageTypeId(evt: Event) {
    if (!evt || !evt.target || !(evt.target instanceof HTMLSelectElement)) return;
    this.pageTypeId = evt.target.value;
  }

  async save() {
    const { language, parentId, title, version } = this;

    if (!parentId || !title || !version) {
      return;
    }

    try {
      const payload = {
        language,
        parentId,
        name: slugify(title),
        version
      };
      const pageVersion = await this.$store.dispatch('pages/create', payload);

      if (this.versionEditor) {
        this.versionEditor.changed = false;
      }
      this.$router.push({
        name: 'page-editor',
        params: { id: pageVersion.page.id }
      });
    } catch (e) {
      await this.addCmsError(e);
    }
  }

  get permissions() {
    return {
      ...this.getPermissions('CmsPage'),
      canDepublish: false
    };
  }

  get orderedAndFilteredTypes() {
    return _orderBy(this.types, 'title').filter((type) => !type.preventCreate);
  }

  get isFolder() {
    return this.pageTypeId === 'Q.Cms.Core.Domain.Folder, Q.Cms.Core.Domain';
  }

  get showLanguageElements() {
    return this.translations && this.languageInfos.length > 1 && !this.isFolder;
  }

  get isValidTitle() {
    return !!this.title && this.title.length >= this.titleMinLength;
  }

  get invalidTitleMessage() {
    return !this.title ? 'Kun je dit veld nog invullen?' : `Vul minimaal ${this.titleMinLength} karakters in`;
  }

  @Watch('title')
  handleTitleChange(title: string) {
    if (this.version) {
      this.version.metaTitle = title;
    }
  }

  @Watch('pageTypeId')
  handlePageTypeIdChange(pageTypeId: string) {
    const selectedPageType = this.types[pageTypeId];
    const { properties } = this.schema;

    this.version = {
      $type: pageTypeId,
      showPostFix: properties['showPostFix'].default ?? true,
      metaIndex: properties['metaIndex'].default ?? true,
      metaFollow: properties['metaFollow'].default ?? true,
      metaTitle: this.title,
      ...initialValue(selectedPageType)
    };
  }
}
</script>
