<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';
  import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';

  export default {
    mixins: [meMixin],

    components: {
      Module,
    },

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

    created() {
      this.$log.debug('**** module.vue created ****');
      this.$log.debug(`||| module id ${this.module.id} |||`);
      this.updateLastVisitedModule(this.module.id);
    },
    mounted() {
      this.$log.debug('**** module.vue mounted ****');
      this.$log.debug(`||| module id ${this.module.id} |||`);
    },

    apollo: {
      module() {
        return {
          query: MODULE_DETAILS_QUERY,
          variables: {
            slug: this.$route.params.slug,
          },
          update(data) {
            return this.$getRidOfEdges(data).module || {};
          },
          // result({data: {module: {id}}}) {
          //   // this.$log.debug(`=== updating result for module ${id} ===`);
          //   // this.updateLastVisitedModule(id);
          // },
          fetchPolicy: 'cache-first',
        };
      },
      scrollPosition: {
        query: SCROLL_POSITION,
      },
    },

    methods: {
      updateLastVisitedModule(moduleId) {
        this.$log.debug(`updating last visited module for module ${moduleId}`);
        if (!moduleId) {
          this.$log.warn('no module id');
          return;
        }
        if (this.me.lastModule.id === moduleId) {
          this.$log.debug('same module already set as last module');
          return;
        }
        this.$apollo.mutate({
          mutation: UPDATE_LAST_MODULE_MUTATION,
          variables: {
            input: {
              id: moduleId,
            },
          },
          update: (store, {data: {updateLastModule: {lastModule}}}) => {
            const {id, slug} = lastModule;
            this.$log.debug('updating last module', id, slug);
            const query = ME_QUERY;
            let {me} = store.readQuery({
              query,
            });
            me.lastModule = {
              id,
              slug,
              __typename: 'ModuleNode',
            };

            if (!me.recentModules || !me.recentModules.edges) {
              me.recentModules = {
                __typename: 'ModuleNodeConnection',
                edges: [],
              };
            }
            const foundIndex = me.recentModules.edges.findIndex(edge => edge.node.slug === lastModule.slug);
            let edges = me.recentModules.edges;
            if (foundIndex > -1) {
              edges = [...edges.slice(0, foundIndex), ...edges.slice(foundIndex + 1, edges.length)];
            }
            me.recentModules.edges = [
              {
                node: lastModule,
                __typename: 'ModuleNodeEdge',
              },
              ...edges.slice(0, 2),
            ];
            store.writeQuery({
              query,
              data: {
                me,
              },
            });
          },

        });
      },
      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>
