<template>
  <div class="content-block__container" :class="{'content-block__container--hidden': hidden}">
    <div class="content-block" :class="specialClass">
      <div class="content-block__actions" v-if="canEditContentBlock && editModule">
        <user-widget v-bind="me" class="content-block__user-widget"></user-widget>
        <more-options-widget>
          <li class="popover-links__link"><a @click="deleteContentBlock()">Löschen</a></li>
          <li class="popover-links__link"><a @click="editContentBlock()">Bearbeiten</a></li>
        </more-options-widget>
      </div>
      <div class="content-block__visibility" v-if="editModule">
        <visibility-action
          v-if="!contentBlock.indent"
          :block="contentBlock"></visibility-action>
        <!--<a @click="editContentBlock()" v-if="canEditContentBlock" class="content-block__action-button">-->
        <!--<pen-icon class="content-block__action-icon action-icon"></pen-icon>-->
        <!--</a>-->
        <!--<a @click="deleteContentBlock(contentBlock.id)" v-if="canEditContentBlock" class="content-block__action-button">-->
        <!--<trash-icon class="content-block__action-icon action-icon"></trash-icon>-->
        <!--</a>-->
      </div>

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

      <component v-for="component in contentBlocksWithContentLists.contents"
                 :key="component.id"
                 :is="component.type"
                 v-bind="component">
      </component>

    </div>

    <add-content-block-button :after="contentBlock.id"
                              v-if="!contentBlock.indent && editModule"></add-content-block-button>

  </div>

</template>

<script>
  import TextBlock from '@/components/content-blocks/TextBlock';
  import InstrumentWidget from '@/components/content-blocks/InstrumentWidget';
  import Task from '@/components/content-blocks/Task';
  import ImageBlock from '@/components/content-blocks/ImageBlock';
  import ImageUrlBlock from '@/components/content-blocks/ImageUrlBlock';
  import VideoBlock from '@/components/content-blocks/VideoBlock';
  import LinkBlock from '@/components/content-blocks/LinkBlock';
  import DocumentBlock from '@/components/content-blocks/DocumentBlock';
  import InfogramBlock from '@/components/content-blocks/InfogramBlock';
  import GeniallyBlock from '@/components/content-blocks/GeniallyBlock';
  import SubtitleBlock from '@/components/content-blocks/SubtitleBlock';
  import ContentListBlock from '@/components/content-blocks/ContentListBlock';
  import Assignment from '@/components/content-blocks/assignment/Assignment';
  import Survey from '@/components/content-blocks/SurveyBlock';
  import Solution from '@/components/content-blocks/Solution';
  import AddContentBlockButton from '@/components/AddContentBlockButton';
  import MoreOptionsWidget from '@/components/MoreOptionsWidget';
  import UserWidget from '@/components/UserWidget';
  import VisibilityAction from '@/components/visibility/VisibilityAction';
  import EyeIcon from '@/components/icons/EyeIcon';
  import PenIcon from '@/components/icons/PenIcon';
  import TrashIcon from '@/components/icons/TrashIcon';

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

  import {meQuery} from '@/graphql/queries';

  import {mapGetters} from 'vuex';

  import {isHidden} from '@/helpers/content-block';

  const instruments = {
    base_communication: 'Sprache & Kommunikation',
    base_society: 'Gesellschaft'
  };

  export default {
    props: ['contentBlock', 'parent'],
    name: 'content-block',

    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,
      'content_list': ContentListBlock,
      Survey,
      Solution,
      Assignment,
      Task,
      AddContentBlockButton,
      VisibilityAction,
      EyeIcon,
      PenIcon,
      TrashIcon,
      MoreOptionsWidget,
      UserWidget
    },

    computed: {
      ...mapGetters(['editModule']),
      specialClass() {
        return `content-block--${this.contentBlock.type.toLowerCase()}`
      },
      instrumentLabel() {
        const contentType = this.contentBlock.type.toLowerCase()
        if (!(contentType in instruments)) {
          return ''
        }

        return `Instrument - ${instruments[contentType]}`
      },
      canEditContentBlock() {
        return this.contentBlock.mine && !this.contentBlock.indent;
      },
      contentBlocksWithContentLists() {
        /*
        collects all conent_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
        }
        if there's only a single content_list_item it should not be displayed as list like so
        {
          text_block,
          content_list_item: [text_block, image_block],
        } becomes
        {
          text_block,
          text_block,
          image_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
              return [...newContents, ...this.createContentListOrBlocks(contentList)];
            }
            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
        });
      },
      schoolClass() {
        return this.me.selectedClass;
      },
      hidden() {
        return isHidden(this.contentBlock, this.schoolClass);
      }
    },

    methods: {
      editContentBlock() {
        this.$store.dispatch('editContentBlock', this.contentBlock.id);
      },
      deleteContentBlock(id) {
        const parent = this.parent;
        this.$apollo.mutate({
          mutation: DELETE_CONTENT_BLOCK_MUTATION,
          variables: {
            input: {
              id: id
            }
          },
          update(store, {data: {deleteContentBlock: {success}}}) {
            try {
              if (success) {
                const query = CHAPTER_QUERY;
                const variables = {
                  id: parent
                };
                const data = store.readQuery({query, variables});
                data.chapter.contentBlocks.edges.splice(data.chapter.contentBlocks.edges.findIndex(edge => edge.node.id === id), 1);
                store.writeQuery({query, variables, data});
              }
            } catch (e) {
              // Query did not exist in the cache, and apollo throws a generic Error. Do nothing
            }
          }
        });
      },
      createContentListOrBlocks(contentList) {
        // if list contains only one item, return blocks
        if (contentList.length === 1) {
          return contentList[0].value;
        }

        return [{
          type: 'content_list',
          contents: contentList,
          id: contentList[0].id
        }];
      },
    },
    data() {
      return {
        showVisibility: false,
        me: {}
      }
    },

    apollo: {
      me: meQuery
    }
  }
</script>

<style scoped lang="scss">
  @import "@/styles/_variables.scss";
  @import "@/styles/_mixins.scss";

  .content-block {
    margin-bottom: 2.5em;
    position: relative;

    &__container {
      position: relative;

      &--hidden {
        &::before {
          content: '';
          position: absolute;
          top: 0;
          left: 0;
          bottom: 0;
          right: 0;
          background: rgba(255, 255, 255, 0.5);
          z-index: 10;
        }
      }
    }

    &__title {
      line-height: 1.5;
    }

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

    &__visibility {
      position: absolute;
      left: -70px;
      top: -4px;
      display: grid;
    }

    &__actions {
      position: absolute;
      top: 10px;
      right: -85px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }

    &__user-widget {
      margin-right: 0;
      margin-bottom: $small-spacing;
    }

    &__action-button {
      cursor: pointer;
    }

    &--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;
        @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;
      }
    }

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

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

    /deep/ .text-block {
      ul {
        padding-left: 25px;
      }

      li {
        list-style: disc;
        line-height: 1.5;
      }
    }

  }
</style>
