<template>
  <module
    :module="module"
    @editNote="editNote"
    @addNote="addNote"
    @bookmark="bookmark"/>
</template>

<script>
  import Module from '@/components/modules/Module';

  import UPDATE_LAST_MODULE_MUTATION from '@/graphql/gql/mutations/updateLastModule.gql';
  import UPDATE_MODULE_BOOKMARK_MUTATION from '@/graphql/gql/mutations/updateModuleBookmark.gql';
  // import ME_QUERY from '@/graphql/gql/meQuery.gql';
  import MODULE_FRAGMENT from '@/graphql/gql/fragments/moduleParts.gql';
  import SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql';
  import SCROLL_TO_MUTATION from '@/graphql/gql/local/mutations/scrollTo.gql';

  import meMixin from '@/mixins/me';
  import MODULE_DETAILS_QUERY from '@/graphql/gql/queries/modules/moduleDetailsQuery';

  export default {
    mixins: [meMixin],

    components: {
      Module
    },

    data() {
      return {
        module: {},
      };
    },

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

    apollo: {
      module() {
        return {
          query: MODULE_DETAILS_QUERY,
          variables: {
            slug: this.$route.params.slug,
          },
          update(data) {
            return this.$getRidOfEdges(data).module || {};
          },
          result() {
            // scroll only after the module has been loaded completely
            // this.scrollTo();
          },
          fetchPolicy: 'cache-first',
        };
      },
      scrollPosition: {
        query: SCROLL_POSITION,
      },
    },

    methods: {
      updateLastVisitedModule(moduleId) {
        if (!moduleId) {
          return;
        }
        this.$apollo.mutate({
          mutation: UPDATE_LAST_MODULE_MUTATION,
          variables: {
            input: {
              id: moduleId,
            },
          },
        });
      },
      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);
      },
      scrollTo() {
        if (this.scrollPosition && this.scrollPosition.scrollTo) {
          let options = {
            container: 'body',
            easing: 'ease',
            offset: -60,
            onStart: (element) => {
            },
            onDone: (element) => {
            },
            onCancel: function () {
              // scrolling has been interrupted
            },
            x: false,
            y: true,
          };
          setTimeout(() => {
            this.$scrollTo(`[data-scrollto="${this.scrollPosition.scrollTo}"]`, 1000, options);
            this.$apollo.mutate({
              mutation: SCROLL_TO_MUTATION,
              variables: {
                scrollTo: '',
              },
            });
          }, 250); // unfortunately this timeout is needed as it is hard to tell when everything is rendered
        }
      },
    },
  };
</script>

<style scoped lang="scss">

</style>
