<!-- Element used to display Blocks in a ContentForm -->
<template>
  <div class="content-element">
    <!-- Element Chooser if element has chooser type or no type -->
    <content-block-element-chooser-widget
      :class="['content-element__component', 'content-element__chooser']"
      v-bind="element"
      v-if="isChooser"
      @change-type="changeType"
      @remove="$emit('remove', false)"
    />

    <!-- Content Forms -->
    <content-form-section
      :title="title"
      :actions="actions"
      v-else
      @top="$emit('top')"
      @up="$emit('up')"
      @down="$emit('down')"
      @bottom="$emit('bottom')"
      @remove="$emit('remove')"
    >
      <div class="content-element__section">
        <!-- Form depending on type of element -->
        <component
          :class="['content-element__component']"
          v-bind="element"
          :is="component"
          @change-text="changeText"
          @link-change-url="changeUrl"
          @change-url="changeUrl"
          @switch-to-document="switchToDocument"
          @assignment-change-title="changeAssignmentTitle"
          @assignment-change-assignment="changeAssignmentAssignment"
          @assignment-change-solution="changeAssignmentSolution"
        />
      </div>
    </content-form-section>
  </div>
</template>

<script lang="ts">
import { defineAsyncComponent } from 'vue';
import ContentFormSection from '@/components/content-block-form/ContentFormSection.vue';
import ContentElementActions from '@/components/content-block-form/ContentElementActions.vue';

const TrashIcon = defineAsyncComponent(() => import('@/components/icons/TrashIcon.vue'));
const ContentBlockElementChooserWidget = defineAsyncComponent(
  () => import('@/components/content-forms/ContentBlockElementChooserWidget.vue')
);
const LinkForm = defineAsyncComponent(() => import('@/components/content-forms/LinkForm.vue'));
const VideoForm = defineAsyncComponent(() => import('@/components/content-forms/VideoForm.vue'));
const ImageForm = defineAsyncComponent(() => import('@/components/content-forms/ImageForm.vue'));
const DocumentForm = defineAsyncComponent(() => import('@/components/content-forms/DocumentForm.vue'));
const AssignmentForm = defineAsyncComponent(() => import('@/components/content-forms/AssignmentForm.vue'));
const TextForm = defineAsyncComponent(
  () => import(/* webpackChunkName: "content-forms" */ '@/components/content-forms/TipTap.vue')
);
const SubtitleForm = defineAsyncComponent(() => import('@/components/content-forms/SubtitleForm.vue'));
const SolutionForm = defineAsyncComponent(() => import('@/components/content-forms/SolutionForm.vue'));
// readonly blocks
const Assignment = defineAsyncComponent(() => import('@/components/content-blocks/assignment/Assignment.vue'));
const SurveyBlock = defineAsyncComponent(() => import('@/components/content-blocks/SurveyBlock.vue'));
const Solution = defineAsyncComponent(() => import('@/components/content-blocks/Solution.vue'));
const ImageBlock = defineAsyncComponent(() => import('@/components/content-blocks/ImageBlock.vue'));
const Instruction = defineAsyncComponent(() => import('@/components/content-blocks/Instruction.vue'));
const ModuleRoomSlug = defineAsyncComponent(() => import('@/components/content-blocks/ModuleRoomSlug.vue'));
const CmsDocumentBlock = defineAsyncComponent(() => import('@/components/content-blocks/CmsDocumentBlock.vue'));
const ThinglinkBlock = defineAsyncComponent(() => import('@/components/content-blocks/ThinglinkBlock.vue'));
const InfogramBlock = defineAsyncComponent(() => import('@/components/content-blocks/InfogramBlock.vue'));
const CHOOSER = 'content-block-element-chooser-widget';

export default {
  props: {
    element: {
      type: Object,
      default: null,
    },
    // is this element at the top level, or is it nested? we assume top level
    topLevel: {
      type: Boolean,
      default: true,
    },
    firstElement: {
      type: Boolean,
      required: true,
    },
    lastElement: {
      type: Boolean,
      required: true,
    },
  },

  components: {
    ContentElementActions,
    ContentFormSection,
    TrashIcon,
    ContentBlockElementChooserWidget,
    LinkForm,
    VideoForm,
    ImageForm,
    DocumentForm,
    AssignmentForm,
    TextForm,
    SubtitleForm,
    SurveyBlock,
    Solution,
    ImageBlock,
    Instruction,
    ModuleRoomSlug,
    CmsDocumentBlock,
    InfogramBlock,
    ThinglinkBlock,
    Assignment,
    SolutionForm,
  },
  computed: {
    actions() {
      return {
        up: !this.firstElement,
        down: !this.lastElement,
        extended: this.topLevel,
      };
    },
    isChooser() {
      return this.component === CHOOSER;
    },
    type() {
      return this.getType(this.element);
    },
    component() {
      return this.type.component;
    },
    title() {
      return this.type.title;
    },
    icon() {
      return this.type.icon;
    },
  },

  methods: {
    getType(element) {
      switch (element.type) {
        case 'subtitle':
          return {
            component: 'subtitle-form',
            title: 'Untertitel',
            icon: 'title-icon',
          };
        case 'link_block':
          return {
            component: 'link-form',
            title: 'Link',
            icon: 'link-icon',
          };
        case 'video_block':
          return {
            component: 'video-form',
            title: 'Video',
            icon: 'video-icon',
          };
        case 'image_url_block':
          return {
            component: 'image-form',
            title: 'Bild',
            icon: 'image-icon',
          };
        case 'text_block':
          return {
            component: 'text-form',
            title: 'Text',
            icon: 'text-icon',
          };
        case 'assignment':
          return {
            component: 'assignment-form',
            title: 'Aufgabe & Ergebnis',
            icon: 'speech-bubble-icon',
          };
        case 'document_block':
          return {
            component: 'document-form',
            title: 'Dokument',
            icon: 'document-icon',
          };
        case 'survey':
          return {
            component: 'survey-block',
            title: 'Übung',
          };
        case 'solution':
          return {
            component: 'solution-form',
            title: 'Lösung',
          };
        case 'image_block':
          return {
            component: 'image-block',
            title: 'Bild',
          };
        case 'instruction':
          return {
            component: 'instruction',
            title: 'Instruktion',
          };
        case 'module_room_slug':
          return {
            component: 'module-room-slug',
            title: 'Raum',
          };
        case 'cms_document_block':
          return {
            component: 'cms-document-block',
            title: 'Dokument',
          };
        case 'thinglink_block':
          return {
            component: 'thinglink-block',
            title: 'Interaktive Grafik',
          };
        case 'infogram_block':
          return {
            component: 'infogram-block',
            title: 'Interaktive Grafik',
          };
      }
      return {
        component: CHOOSER,
        title: '',
        icon: '',
      };
    },
    _updateProperty(value, key) {
      // const content = this.localContentBlock.contents[index];
      const content = this.element;
      this.update({
        ...content,
        value: {
          ...content.value,
          [key]: value,
        },
      });
    },
    changeUrl(value) {
      this._updateProperty(value, 'url');
    },
    changeText(value) {
      this._updateProperty(value, 'text');
    },
    changeAssignmentTitle(value) {
      this._updateProperty(value, 'title');
    },
    changeAssignmentAssignment(value) {
      this._updateProperty(value, 'assignment');
    },
    changeAssignmentSolution(value) {
      this._updateProperty(value, 'solution');
    },
    changeType({ type, convertToList }, value) {
      let el = {
        type: type,
        value: Object.assign({}, value),
      };
      switch (type) {
        case 'subtitle':
          el = {
            ...el,
            value: {
              text: '',
            },
          };
          break;
        case 'text_block':
          el = {
            ...el,
            value: {
              text: '',
            },
          };
          break;
        case 'link_block':
          el = {
            ...el,
            value: {
              text: '',
              url: '',
            },
          };
          break;
        case 'video_block':
          el = {
            ...el,
            value: {
              url: '',
            },
          };
          break;
        case 'document_block':
          el = {
            ...el,
            value: Object.assign(
              {
                url: '',
              },
              value
            ),
          };
          break;
        case 'image_url_block':
          el = {
            ...el,
            value: {
              url: '',
            },
          };
          break;
      }

      if (convertToList) {
        el = {
          type: 'content_list_item',
          contents: [el],
        };
      }
      this.update(el);
    },
    update(element) {
      this.$emit('update', element);
    },
    switchToDocument(value) {
      this.changeType('document_block', value);
    },
  },
};
</script>

<style scoped lang="scss">
@import 'styles/helpers';

.content-element {
  display: flex;
  flex-direction: column;

  &__actions {
    display: inline-flex;
    justify-self: flex-end;
    align-self: flex-end;
  }

  &__section {
    display: grid;
    //grid-template-columns: 1fr 50px;
    grid-auto-rows: auto;
    /*width: 95%; // reserve space for scrollbar*/
  }

  &__chooser {
    grid-column: 1 / span 2;
  }
}
</style>
