<template>
  <div class="topic">
    <div class="topic__navigation">
      <topic-navigation />
    </div>

    <div class="topic__content">
      <h1
        data-cy="topic-title"
        class="topic__title"
      >
        {{ topic.title }}
      </h1>
      <p class="topic__teaser">
        {{ topic.teaser }}
      </p>

      <div class="topic__links">
        <div
          class="topic__video-link topic__link"
          v-if="topic.vimeoId"
          @click="openVideo"
        >
          <play-icon class="topic__video-link-icon topic__link-icon" />
          <span class="topic__link-description">Video schauen</span>
        </div>
        <a
          :href="topic.instructions"
          target="_blank"
          class="topic__instruction-link topic__link"
          v-if="me.isTeacher && topic.instructions"
        >
          <bulb-icon class="topic__instruction-icon topic__link-icon" />
          <span class="topic__link-description">Anweisungen zum {{ $flavor.textTopic }} anzeigen</span>
        </a>
      </div>
      <div class="topic__modulefilter">
        <module-filter
          :modules="modules"
          :me="me"
          v-if="modules.length > 0"
        ></module-filter>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import ModuleFilter from '@/components/modules/ModuleFilter.vue';
import { defineAsyncComponent } from 'vue';
import TOPIC_QUERY from '@/graphql/gql/queries/topicQuery.gql';
import me from '@/mixins/me';
import TopicNavigation from '@/components/book-navigation/TopicNavigation.vue';

import UPDATE_LAST_TOPIC_MUTATION from '@/graphql/gql/mutations/updateLastTopic.gql';
import ME_QUERY from '@/graphql/gql/queries/meQuery.gql';

const PlayIcon = defineAsyncComponent(() => import('@/components/icons/Play.vue'));
const BulbIcon = defineAsyncComponent(() => import('@/components/icons/BulbIcon.vue'));

export default {
  mixins: [me],
  components: {
    TopicNavigation,
    PlayIcon,
    BulbIcon,
    ModuleFilter,
  },

  apollo: {
    topic() {
      return {
        query: TOPIC_QUERY,
        variables: {
          slug: this.$route.params.topicSlug,
        },
        update(data) {
          return this.$getRidOfEdges(data).topic || {};
        },
        result() {
          if (this.saveMe) {
            this.saveMe = false;
            this.updateLastVisitedTopic(this.topic.id);
          }
        },
      };
    },
  },

  data() {
    return {
      topic: {
        modules: [],
      },
      saveMe: false,
    };
  },

  computed: {
    modules() {
      return this.topic.modules;
    },
  },

  mounted() {
    if (!this.topic.id) {
      // component was loaded before topic, apollo not ready yet
      this.saveMe = true; // needs saving, apollo will do this
    } else {
      this.updateLastVisitedTopic(this.topic.id);
    }
  },

  methods: {
    openVideo() {
      this.$store.dispatch('showFullscreenVideo', this.topic.vimeoId);
    },
    updateLastVisitedTopic(topicId) {
      if (!topicId) {
        return;
      }
      this.$apollo.mutate({
        mutation: UPDATE_LAST_TOPIC_MUTATION,
        variables: {
          input: {
            id: topicId,
          },
        },
        update(
          store,
          {
            data: {
              updateLastTopic: { topic },
            },
          }
        ) {
          if (topic) {
            const query = ME_QUERY;
            try {
              const { me } = store.readQuery({ query });
              if (me) {
                const data = {
                  me: {
                    ...me,
                    lastTopic: topic,
                  },
                };
                store.writeQuery({ query, data });
              }
            } catch (error: unknown) {
              if (!(error instanceof TypeError)) {
                throw error;
              }
              // otherwise, the store didn't contain the data, this is fine, we ignore it
            }
          }
        },
      });
    },
  },
};
</script>

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

.topic {
  display: grid;
  padding: $large-spacing $small-spacing;
  @include desktop {
    padding: $large-spacing 0;
  }
  grid-template-columns: 1fr;
  max-width: $topic-mobile-width;
  justify-self: center;
  @include desktop {
    max-width: 1500px; // 300px (sidebar) + 3x 380 (max width teaser) + 2x 60 (column gap)
    grid-template-columns: 300px 1fr;
    justify-self: flex-start;
  }

  &__navigation {
    padding: 0 $medium-spacing;
    display: none;
    @include desktop {
      display: block;
    }
  }

  &__teaser {
    color: $color-charcoal-dark;
    width: 90%;
    @include lead-paragraph;
    margin-bottom: $large-spacing;
  }

  &__links {
    margin-bottom: $large-spacing;
    display: flex;
  }

  &__link {
    cursor: pointer;
    display: flex;
    align-items: center;
  }

  &__video-link {
    margin-right: $large-spacing;
  }

  &__link-icon {
    width: 40px;
    height: 40px;
    margin-right: $medium-spacing;
  }

  &__link-description {
    @include heading-3;
  }
}
</style>
