<template>
  <div class="module">
    <h2 class="module__meta-title" id="meta-title">{{module.metaTitle}}</h2>
    <h1 class="module__title" data-cy="module-title">{{module.title}}</h1>
    <img
      :src="module.heroImage"
      alt="" class="module__hero">

    <div class="module__intro-wrapper">
      <bookmark-actions
        class="module__bookmark-actions"
        @add-note="addNote"
        @edit-note="editNote"
        :bookmarked="module.bookmark"
        :note="note"
        @bookmark="bookmark(!module.bookmark)"></bookmark-actions>
      <div class="module__intro" v-html="module.intro"></div>
    </div>

    <h3 id="objectives">Lernziele</h3>

    <objective-groups :groups="languageCommunicationObjectiveGroups"></objective-groups>

    <objective-groups :groups="societyObjectiveGroups"></objective-groups>

    <chapter :chapter="chapter" :index="index" v-for="(chapter, index) in module.chapters" :key="chapter.id"></chapter>

  </div>
</template>

<script>
  import ObjectiveGroups from '@/components/objective-groups/ObjectiveGroups.vue';
  import ObjectiveGroupControl from '@/components/objective-groups/ObjectiveGroupControl.vue';
  import Chapter from '@/components/Chapter.vue';

  import UPDATE_OBJECTIVE_PROGRESS_MUTATION from '@/graphql/gql/mutations/updateObjectiveProgress.gql';
  import UPDATE_LAST_MODULE_MUTATION from '@/graphql/gql/mutations/updateLastModule.gql';
  import UPDATE_MODULE_BOOKMARK_MUTATION from '@/graphql/gql/mutations/updateModuleBookmark.gql';
  import OBJECTIVE_QUERY from '@/graphql/gql/objectiveQuery.gql';
  import ME_QUERY from '@/graphql/gql/meQuery.gql';
  import MODULE_FRAGMENT from '@/graphql/gql/fragments/moduleParts.gql';

  import {withoutOwnerFirst} from '@/helpers/sorting';
  import BookmarkActions from '@/components/notes/BookmarkActions';

  export default {
    components: {
      BookmarkActions,
      ObjectiveGroups,
      ObjectiveGroupControl,
      Chapter
    },

    props: {
      module: {
        required: true,
        type: Object
      },
      edit: {
        type: Boolean,
        default: false
      }
    },

    created() {
      this.updateLastVisitedModule(this.module.id)
    },

    computed: {
      languageCommunicationObjectiveGroups() {
        return this.module.objectiveGroups ? this.module.objectiveGroups
          .filter(group => group.title === 'LANGUAGE_COMMUNICATION')
          .sort(withoutOwnerFirst) : [];
      },
      societyObjectiveGroups() {
        return this.module.objectiveGroups ? this.module.objectiveGroups
          .filter(group => group.title === 'SOCIETY')
          .sort(withoutOwnerFirst) : [];
      },
      isStudent() {
        return !this.me.permissions.includes('users.can_manage_school_class_content');
      },
      note() {
        if (!(this.module && this.module.bookmark)) {
          return;
        }
        return this.module.bookmark.note;
      }
    },

    methods: {
      updateLastVisitedModule(moduleId) {
        this.$apollo.mutate({
          mutation: UPDATE_LAST_MODULE_MUTATION,
          variables: {
            input: {
              id: moduleId
            }
          },
          update(store, {data: {updateLastModule: {module}}}) {
            if (module) {
              const data = store.readQuery({query: ME_QUERY});
              if (data) {
                data.me.lastModule = module;
                store.writeQuery({query: ME_QUERY, data});
              }
            }
          }
        });
      },
      updateObjectiveProgress(done, objectiveId) {
        this.$apollo.mutate({
          mutation: UPDATE_OBJECTIVE_PROGRESS_MUTATION,
          variables: {
            input: {
              id: objectiveId,
              done: done
            }
          },
          update(store, {data: {updateObjectiveProgress: {objective}}}) {
            if (objective) {
              const variables = {id: objectiveId};
              const query = OBJECTIVE_QUERY;
              const data = store.readQuery({query, variables});
              if (data && data.objective.objectiveProgress.edges.length > 0) {
                data.objective.objectiveProgress.edges[0].node.done = done;
              }
              store.writeQuery({query: OBJECTIVE_QUERY, data, variables});
            }
          }
        })
      },
      bookmark(bookmarked) {
        const slug = this.module.slug;
        this.$apollo.mutate({
          mutation: UPDATE_MODULE_BOOKMARK_MUTATION,
          variables: {
            input: {
              module: slug,
              bookmarked
            }
          },
          update: (store, response) => {
            const fragment = MODULE_FRAGMENT;
            const id = `ModuleNode:${slug}`;
            const data = store.readFragment({
              fragment,
              id
            });

            if (bookmarked) {
              data.bookmark = {
                __typename: 'ModuleBookmarkNode',
                note: null
              }
            } else {
              data.bookmark = null;
            }

            store.writeFragment({
              data,
              fragment,
              id
            });
          },
          optimisticResponse: {
            __typename: 'Mutation',
            updateModuleBookmark: {
              __typename: 'UpdateModuleBookmarkPayload',
              success: true
            }
          }
        });
      },
      addNote(id) {
        this.$store.dispatch('addNote', {
          content: id,
          parent: this.module.id
        });
      },
      editNote() {
        this.$store.dispatch('editNote', this.module.bookmark.note);
      },
    },

    apollo: {
      me: {
        query: ME_QUERY,
      }
    },

    data() {
      return {
        me: {
          permissions: []
        }
      }
    }
  }
</script>

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

  .module {
    display: flex;
    justify-self: center;

    @include desktop {
      width: 800px;
    }
    flex-direction: column;
    padding: $large-spacing 15px;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;

    &__hero {
      margin-bottom: 35px;
      border-radius: 12px;
      max-width: 100%;
    }

    &__meta-title {
      @include meta-title;
    }

    &__intro-wrapper {
      position: relative;
    }

    &__intro {
      line-height: 1.5;
      margin-bottom: 3em;

      > /deep/ p {
        font-size: toRem(25px);
        margin-bottom: 1.5em;

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

    &__bookmark-actions {
      margin-top: 3px;
    }

  }
</style>
