<template>
  <div
    :class="componentClass"
    :data-scrollto="component.id"
    :data-uuid="component.id"
    data-cy="content-component"
  >
    <bookmark-actions
      :bookmarked="bookmarked"
      :note="note"
      :edit-mode="editMode"
      v-if="showBookmarkActions"
      @add-note="addNote(component.id)"
      @edit-note="editNote"
      @bookmark="bookmarkContent(component.id, !bookmarked)"
    />
    <component
      v-bind="component"
      :parent="parent"
      :is="component.type"
    />
  </div>
</template>

<script>
import { constructContentComponentBookmarkMutation } from '@/helpers/update-content-bookmark-mutation';
import { defineAsyncComponent } from 'vue';

const TextBlock = defineAsyncComponent(() => import('@/components/content-blocks/TextBlock.vue'));
const InstrumentWidget = defineAsyncComponent(() => import('@/components/content-blocks/InstrumentWidget.vue'));
const ImageBlock = defineAsyncComponent(() => import('@/components/content-blocks/ImageBlock.vue'));
const ImageUrlBlock = defineAsyncComponent(() => import('@/components/content-blocks/ImageUrlBlock.vue'));
const VideoBlock = defineAsyncComponent(() => import('@/components/content-blocks/VideoBlock.vue'));
const LinkBlock = defineAsyncComponent(() => import('@/components/content-blocks/LinkBlock.vue'));
const DocumentBlock = defineAsyncComponent(() => import('@/components/content-blocks/DocumentBlock.vue'));
const CmsDocumentBlock = defineAsyncComponent(() => import('@/components/content-blocks/CmsDocumentBlock.vue'));
const InfogramBlock = defineAsyncComponent(() => import('@/components/content-blocks/InfogramBlock.vue'));
const ThinglinkBlock = defineAsyncComponent(() => import('@/components/content-blocks/ThinglinkBlock.vue'));
const GeniallyBlock = defineAsyncComponent(() => import('@/components/content-blocks/GeniallyBlock.vue'));
const SubtitleBlock = defineAsyncComponent(() => import('@/components/content-blocks/SubtitleBlock.vue'));
const SectionTitleBlock = defineAsyncComponent(() => import('@/components/content-blocks/SectionTitleBlock.vue'));
const ContentListBlock = defineAsyncComponent(() => import('@/components/content-blocks/ContentListBlock.vue'));
const ModuleRoomSlug = defineAsyncComponent(() => import('@/components/content-blocks/ModuleRoomSlug.vue'));
const Assignment = defineAsyncComponent(() => import('@/components/content-blocks/assignment/Assignment.vue'));
const Survey = defineAsyncComponent(() => import('@/components/content-blocks/SurveyBlock.vue'));
const Solution = defineAsyncComponent(() => import('@/components/content-blocks/Solution.vue'));
const Instruction = defineAsyncComponent(() => import('@/components/content-blocks/Instruction.vue'));
const BookmarkActions = defineAsyncComponent(() => import('@/components/notes/BookmarkActions.vue'));

export default {
  props: {
    component: {
      type: Object,
      default: () => ({}),
    },
    parent: {
      type: Object,
      default: () => ({}),
    },
    bookmarks: {
      type: Array,
      default: () => [],
    },
    notes: {
      type: Array,
      default: () => [],
    },
    root: {
      type: String,
      default: '',
    },
    editMode: {
      type: Boolean,
      default: false,
    },
  },

  components: {
    text_block: TextBlock,
    basic_knowledge: InstrumentWidget, // for legacy
    instrument: InstrumentWidget,
    image_block: ImageBlock,
    image_url_block: ImageUrlBlock,
    video_block: VideoBlock,
    link_block: LinkBlock,
    document_block: DocumentBlock,
    infogram_block: InfogramBlock,
    genially_block: GeniallyBlock,
    subtitle: SubtitleBlock,
    section_title: SectionTitleBlock,
    content_list: ContentListBlock,
    module_room_slug: ModuleRoomSlug,
    thinglink_block: ThinglinkBlock,
    cms_document_block: CmsDocumentBlock,
    Survey,
    Solution,
    Instruction,
    Assignment,
    BookmarkActions,
  },

  computed: {
    bookmarked() {
      return this.bookmarks && !!this.bookmarks.find((bookmark) => bookmark.uuid === this.component.id);
    },
    note() {
      const bookmark = this.bookmarks && this.bookmarks.find((bookmark) => bookmark.uuid === this.component.id);
      return bookmark && bookmark.note;
    },
    showBookmarkActions() {
      return this.component.type !== 'content_list' && this.component.type !== 'basic_knowledge' && !this.editMode;
    },
    componentClass() {
      let classes = ['content-component', `content-component--${this.component.type}`];
      if (this.bookmarked) {
        classes.push('content-component--bookmarked');
      }
      return classes;
    },
  },

  methods: {
    addNote(id) {
      const type = Object.prototype.hasOwnProperty.call(this.parent, '__typename')
        ? this.parent.__typename
        : 'ContentBlockNode';

      this.$store.dispatch('addNote', {
        content: id,
        type,
        block: this.root,
      });
    },
    editNote() {
      this.$store.dispatch('editNote', this.note);
    },
    bookmarkContent(uuid, bookmarked) {
      this.$apollo.mutate(constructContentComponentBookmarkMutation(uuid, bookmarked, this.parent, this.root));
    },
  },
};
</script>

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

.content-component {
  position: relative;

  &--bookmarked {
  }

  &--subtitle {
    margin-top: 2 * $medium-spacing;
    margin-bottom: $medium-spacing;
  }

  &--section_title {
    margin-top: $section-spacing;
    margin-bottom: $large-spacing;
  }

  &--text_block {
    margin-bottom: $large-spacing;
  }

  &--document_block {
    margin-bottom: $large-spacing;
  }
}
</style>
