<template>
  <div v-if="itemId && initialized">
    <editor-translations :type="entityType" :translations="translations" @click="switchTranslation" />
    <template v-if="!isNewItem && hasTranslatableLanguages">
      <button class="btn btn-light btn-block" @click="addItemTranslationModal.open(itemId, languageRef)" :disabled="loading">Vertaling toevoegen</button>
      <add-item-translation-modal
        ref="addItemTranslationModal"
        :translations="translations"
        :translatable-languages="translatableLanguages"
        :item-id="itemId"
        :language-ref="languageRef"
        :module="module"
        @add="handleAdd"
      />
    </template>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Ref, Watch } from 'vue-property-decorator';
import { namespace } from 'vuex-class';

import AddItemTranslationModal from './add-item-translation-modal.vue';
import EntityTranslationsProvider from './entity-translations-provider.vue';
import EditorTranslations from './editor-translations.vue';
import { EntityType, ItemTranslation, SupportedLanguage } from '../../types/language';
import LanguageApi from '../../api/language-api';
import { RawLocation, Route } from 'vue-router';
import RouteUtils, { createRoute, ROUTES } from '../../tools/route-utils';

const LanguageStore = namespace('languages');

@Component({
  components: {
    AddItemTranslationModal,
    EntityTranslationsProvider,
    EditorTranslations
  }
})
export default class CrudEditorTranslations extends EntityTranslationsProvider<ItemTranslation> {
  @Prop(String) readonly languageRef!: string;
  @Prop(String) readonly itemId!: string;
  @Prop(Boolean) readonly isSingleton!: boolean;
  @Prop(String) readonly module!: string;
  @Prop(String) readonly name!: string;

  entityType = EntityType.Item;
  isNewItem = false;

  @Ref() readonly addItemTranslationModal!: AddItemTranslationModal;

  @LanguageStore.State('all') readonly allLanguages!: SupportedLanguage[];

  async beforeMount() {
    await this.initialize(() => LanguageApi.getItemTranslations(this.module, this.languageRef));

    // Check initial component mount for non-existing translation for current language and redirect to empty state accordingly.
    if (!this.getTranslationByKey(this.selectedLanguage.key)?.itemId && !this.isEmptyStateRoute) {
      await RouteUtils.replace(this.emptyStateRoute);
    }
  }

  // Switch from translation list in editor-translations.vue
  async switchTranslation(translation: ItemTranslation) {
    const language = this.allLanguages.find(language => language.key === translation.language);

    if (language && this.selectedLanguage !== language) {
      translation.itemId
        ? await this.setSelectedLanguage(language)
        : this.addItemTranslationModal.open(translation.language);
    }
  }

  async handleItemTranslationSwitch(to: Route, from: Route, next: (to?: RawLocation | false) => void) {
    if (to.params.lang !== from.params.lang) {
      const currentTranslation = this.getTranslationByKey(from.params.lang);
      const translation = this.getTranslationByKey(to.params.lang);

      if (!translation || !currentTranslation) {
        next();
        return;
      }

      // ItemId of null means the item is not translated and therefore we should redirect to the empty state
      if (!translation.itemId) {
        // Current page is the empty state so another redirect would be a duplicate, unnecessary route push
        if (!currentTranslation.itemId) {
          next();
          return;
        }

        next(this.emptyStateRoute);
      } else if (translation.itemId !== to.params.id && !this.isSingleton) {
        next(createRoute(ROUTES.CRUD_EDITOR(this.module), { id: translation.itemId }));
      } else {
        next();
      }
    } else {
      next();
    }
  }

  async handleAdd(language: SupportedLanguage) {
    await this.update(language);

    const translation = this.getTranslationByKey(language.key);
    if (this.isEmptyStateRoute && translation?.itemId) {
      await RouteUtils.replace(createRoute(ROUTES.CRUD_EDITOR(this.module), { id: translation.itemId }));
    }
  }

  get emptyStateRoute() {
    return createRoute(ROUTES.CRUD_EMPTY_TRANSLATION(this.module), null, {
      query: { itemId: this.itemId, languageRef: this.languageRef, itemName: this.name }
    });
  }

  get isEmptyStateRoute() {
    return this.$route.name === ROUTES.CRUD_EMPTY_TRANSLATION(this.module);
  }

  get isNewSingleton() {
    return this.isSingleton && !this.itemId;
  }

  get translatableLanguages() {
    return this.allLanguages.filter(language => !this.translations.some(translation => translation.language === language.key && translation.itemId));
  }

  get hasTranslatableLanguages() {
    return this.translatableLanguages.length > 0;
  }

  @Watch('translations')
  onTranslationsChange(translations: ItemTranslation[]) {
    this.isNewItem = translations.filter(translation => translation.itemId).length === 0;
  }
}
</script>
