<template>
  <div
    :class="{'hideable-element--greyed-out': hidden}"
    class="content-block__container hideable-element content-list__parent"
  >
    <div
      :class="specialClass"
      :style="instrumentStyle"
      class="content-block"
      data-cy="content-block"
    >
      <div
        class="block-actions"
        v-if="canEditContentBlock && editMode"
      >
        <user-widget
          v-bind="me"
          class="block-actions__user-widget content-block__user-widget"
        />
        <more-options-widget>
          <li class="popover-links__link">
            <popover-link
              data-cy="delete-content-block-link"
              text="Löschen"
              @link-action="deleteContentBlock(contentBlock)"
            />
          </li>

          <li class="popover-links__link">
            <popover-link
              text="Bearbeiten"
              @link-action="editContentBlock(contentBlock)"
            />
          </li>
        </more-options-widget>
      </div>
      <div class="content-block__visibility">
        <visibility-action
          :block="contentBlock"
          v-if="canEditModule"
        />
      </div>

      <h3
        class="content-block__instrument-label"
        data-cy="instrument-label"
        :style="instrumentLabelStyle"
        v-if="instrumentLabel !== ''"
      >
        {{ instrumentLabel }}
      </h3>
      <h4
        class="content-block__title"
        v-if="!contentBlock.indent"
      >
        {{ contentBlock.title }}
      </h4>

      <content-component
        :component="component"
        :root="root"
        :parent="contentBlock"
        :bookmarks="contentBlock.bookmarks"
        :notes="contentBlock.notes"
        :edit-mode="editMode"
        v-for="component in contentBlocksWithContentLists.contents"
        :key="component.id"
      />
    </div>

    <add-content-button
      :where="{after: contentBlock}"
      v-if="canEditModule"
    />
  </div>
</template>

<script>
  import AddContentButton from '@/components/AddContentButton';
  import MoreOptionsWidget from '@/components/MoreOptionsWidget';
  import UserWidget from '@/components/UserWidget';
  import VisibilityAction from '@/components/visibility/VisibilityAction';

  import CHAPTER_QUERY from '@/graphql/gql/queries/chapterQuery.gql';
  import DELETE_CONTENT_BLOCK_MUTATION from '@/graphql/gql/mutations/deleteContentBlock.gql';

  import me from '@/mixins/me';

  import {hidden} from '@/helpers/visibility';
  import {CONTENT_TYPE} from '@/consts/types';
  import PopoverLink from '@/components/ui/PopoverLink';
  import {removeAtIndex} from '@/graphql/immutable-operations';
  import {EDIT_CONTENT_BLOCK_PAGE} from '@/router/module.names';
  import {instrumentCategory} from '@/helpers/instrumentType';

  const ContentComponent = () => import(/* webpackChunkName: "content-components" */'@/components/content-blocks/ContentComponent');


  export default {
    name: 'ContentBlock',
    props: {
      contentBlock: {
        type: Object,
        default: () => ({}),
      },
      parent: {
        type: Object,
        default: () => ({}),
      },
      editMode: {
        type: Boolean,
        default: true,
      },
    },

    mixins: [me],

    components: {
      PopoverLink,
      ContentComponent,
      AddContentButton,
      VisibilityAction,
      MoreOptionsWidget,
      UserWidget,
    },

    computed: {
      canEditModule() {
        return !this.contentBlock.indent && this.editMode;
      },
      specialClass() {
        return `content-block--${this.contentBlock.type.toLowerCase()}`;
      },
      isInstrumentBlock() {
        return !!this.contentBlock.instrumentCategory;
      },
      instrumentStyle() {
        if (this.isInstrumentBlock) {
          return {
            backgroundColor: this.contentBlock.instrumentCategory.background
          };
        }
        return {};
      },
      instrumentLabel() {
        const contentType = this.contentBlock.type.toLowerCase();
        if (contentType.startsWith('base')) { // all legacy instruments start with `base`
          return instrumentCategory(contentType);
        }
        if (this.isInstrumentBlock) {
          return instrumentCategory(this.contentBlock.instrumentCategory.name);
        }
        return '';
      },
      instrumentLabelStyle() {
        if (this.isInstrumentBlock) {
          return {
            color: this.contentBlock.instrumentCategory.foreground
          };
        }
        return {};
      },
      canEditContentBlock() {
        return this.contentBlock.mine && !this.contentBlock.indent;
      },
      contentBlocksWithContentLists() {
        /*
        collects all content_list_items in content_lists:
        {
          text_block,
          content_list_item: [contents...],
          content_list_item: [contents...],
          text_block
        } becomes
        {
          text_block,
          content_list: [content_list_item: [contents...], content_list_item: [contents...]],
          text_block
        }
        */
        let contentList = [];
        let newContent = this.contentBlock.contents.reduce((newContents, content, index) => {
          // collect content_list_items
          if (content.type === 'content_list_item') {
            contentList = [...contentList, content];
            if (index === this.contentBlock.contents.length - 1) { // content is last element of contents array
              let updatedContent = [...newContents, ...this.createContentListOrBlocks(contentList)];
              return updatedContent;
            }
            return newContents;
          } else {
            // handle all other items and reset current content_list if necessary
            if (contentList.length !== 0) {
              newContents = [...newContents, ...this.createContentListOrBlocks(contentList), content];
              contentList = [];
              return newContents;
            } else {
              return [...newContents, content];
            }
          }
        }, []);
        return Object.assign({}, this.contentBlock, {
          contents: newContent,
        });
      },
      hidden() {
        return hidden({
          block: this.contentBlock,
          schoolClass: this.schoolClass,
          type: CONTENT_TYPE,
        });
      },
      root() {
        // we need the root content block id, not the generated content block if inside a content list block
        return this.contentBlock.root ? this.contentBlock.root : this.contentBlock.id;
      },
    },
    methods: {
      editContentBlock(contentBlock) {
        const route = {
          name: EDIT_CONTENT_BLOCK_PAGE,
          params: {
            id: contentBlock.id,
          },
        };
        this.$router.push(route);
      },
      deleteContentBlock(contentBlock) {
        this.$modal.open('confirm').then(() => {
            this.doDeleteContentBlock(contentBlock);
          })
          .catch();
      },
      doDeleteContentBlock(contentBlock) {
        const parent = this.parent;
        const id = contentBlock.id;
        this.$apollo.mutate({
          mutation: DELETE_CONTENT_BLOCK_MUTATION,
          variables: {
            input: {
              id,
            },
          },
          update(store, {data: {deleteContentBlock: {success}}}) {
            if (success) {
              const query = CHAPTER_QUERY;
              const variables = {
                id: parent.id,
              };
              const {chapter} = store.readQuery({query, variables});
              const index = chapter.contentBlocks.findIndex(contentBlock => contentBlock.id === id);
              const contentBlocks = removeAtIndex(chapter.contentBlocks, index);
              const data = {
                chapter: {
                  ...chapter,
                  contentBlocks,
                },
              };
              store.writeQuery({query, variables, data});
            }
          },
        });
      },
      createContentListOrBlocks(contentList) {
        return [{
          type: 'content_list',
          contents: contentList,
          id: contentList[0].id,
        }];
      },
    },
  };
</script>

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

  .content-block {
    margin-bottom: $section-spacing;
    position: relative;

    &__container {
      position: relative;
    }

    &__title {
      line-height: 1.5;
      margin-top: -0.5rem; // to offset the 1.5 line height, it leaves a padding on top
    }

    &__instrument-label {
      margin-bottom: $medium-spacing;
      @include regular-text();
    }

    &__action-button {
      cursor: pointer;
    }

    &__user-widget {
      margin-right: 0;
    }

    &--base_communication {
      @include content-box($color-accent-1-list);

      .content-block__instrument-label {
        color: $color-accent-1-dark;
      }
    }

    &--task {
      @include light-border(bottom);

      .content-block__title {
        color: $color-brand;
        margin-top: $default-padding;
        margin-bottom: $large-spacing;
        @include light-border(bottom);

        @include desktop {
          margin-top: 0;
        }
      }
    }

    &--base_society {
      @include content-box($color-accent-2-list);

      .content-block__instrument-label {
        color: $color-accent-2-dark;
      }
    }

    &--base_interdisciplinary {
      @include content-box($color-accent-4-list);

      .content-block__instrument-label {
        color: $color-accent-4-dark;
      }
    }

    &--instrument {
      @include content-box-base;
    }

    /deep/ p {
      line-height: 1.5;
      margin-bottom: 1em;

      &:last-child {
        margin-bottom: 0;
      }
    }

    /deep/ .text-block {
      ul {
        @include list-parent;
      }

      li {
        @include list-child;
        line-height: 1.5;
      }
    }

  }
</style>
