﻿<script setup>
import { REACTIONS } from "@/Constants/Reactions.js";
import { computed, ref } from "vue";
import { useClient } from "@/plugins/api.js";
import {useAuthStore} from "@/stores/authStore.js"
import MustBeLogged from "@/views/MustBeLogged.vue";
import {useUserProfileStore} from "@/stores/userProfileStore.js";

const userProfileStore = useUserProfileStore();
const authStore = useAuthStore()

const props = defineProps({
  content: {
    type: Object,
    required: true,
  },
});

const contentId = computed(() => props.content.id);

const hasReacted = ref(false);
const currentReaction = ref(null);
const likeCount = ref(0);
const dislikeCount = ref(0);
const loveCount = ref(0);
const hahaCount = ref(0);
const wowCount = ref(0);
const sadCount = ref(0);
const angryCount = ref(0);

const menuVisible = ref(false);
const holdTimeout = ref(null);
const hideTimeout = ref(null);
const touchTimeout = ref(null);

const loginModal = ref(false);

initializeReactions();

async function reactToContent(reaction) {
  if (!authStore.isAuthenticated) {
    loginModal.value = true;
    return;
  }
  
  const client = useClient();

  if (!hasReacted.value) {
    const request = {
      ContentId: contentId.value,
      reaction: reaction,
      userId: userProfileStore.user.id,
      userName: `${userProfileStore.user.firstName} ${userProfileStore.user.lastName}`,
    };
    adjustReactionCount(reaction);
    await client.post("/api/content/reaction/", request);

    hasReacted.value = true;
    console.log(`Added ${reaction} reaction to content.`);
  } else if (reaction !== currentReaction.value) {
    const requestAdd = {
      ContentId: contentId.value,
      reaction: reaction,
      userId: userProfileStore.user.id,
      userName: `${userProfileStore.user.firstName} ${userProfileStore.user.lastName}`,
    };
    adjustReactionCount(reaction);
    await client.post("/api/content/reaction/", requestAdd);

    console.log(`Changed reaction to ${reaction} on content.`);
  } else {
    const requestRemove = {
      ContentId: contentId.value,
      userId: userProfileStore.user.id,
    };
    adjustReactionCount(reaction);
    await client.post("/api/content/reaction/remove", requestRemove);

    hasReacted.value = false;
    console.log("Reaction to content removed.");
  }
  setTimeout(() => {
    menuVisible.value = false;
  }, 500);
}

function adjustReactionCount(newReaction) {
  if (currentReaction.value === newReaction) {
    switch (newReaction) {
      case REACTIONS.LIKE:
        if (likeCount.value > 0) likeCount.value--;
        break;
      case REACTIONS.DISLIKE:
        if (dislikeCount.value > 0) dislikeCount.value--;
        break;
      case REACTIONS.LOVE:
        if (loveCount.value > 0) loveCount.value--;
        break;
      case REACTIONS.HAHA:
        if (hahaCount.value > 0) hahaCount.value--;
        break;
      case REACTIONS.WOW:
        if (wowCount.value > 0) wowCount.value--;
        break;
      case REACTIONS.SAD:
        if (sadCount.value > 0) sadCount.value--;
        break;
      case REACTIONS.ANGRY:
        if (angryCount.value > 0) angryCount.value--;
        break;
    }
    currentReaction.value = null;
    hasReacted.value = false;
  } else {
    if (currentReaction.value) {
      switch (currentReaction.value) {
        case REACTIONS.LIKE:
          if (likeCount.value > 0) likeCount.value--;
          break;
        case REACTIONS.DISLIKE:
          if (dislikeCount.value > 0) dislikeCount.value--;
          break;
        case REACTIONS.LOVE:
          if (loveCount.value > 0) loveCount.value--;
          break;
        case REACTIONS.HAHA:
          if (hahaCount.value > 0) hahaCount.value--;
          break;
        case REACTIONS.WOW:
          if (wowCount.value > 0) wowCount.value--;
          break;
        case REACTIONS.SAD:
          if (sadCount.value > 0) sadCount.value--;
          break;
        case REACTIONS.ANGRY:
          if (angryCount.value > 0) angryCount.value--;
          break;
      }
    }

    switch (newReaction) {
      case REACTIONS.LIKE:
        likeCount.value++;
        break;
      case REACTIONS.DISLIKE:
        dislikeCount.value++;
        break;
      case REACTIONS.LOVE:
        loveCount.value++;
        break;
      case REACTIONS.HAHA:
        hahaCount.value++;
        break;
      case REACTIONS.WOW:
        wowCount.value++;
        break;
      case REACTIONS.SAD:
        sadCount.value++;
        break;
      case REACTIONS.ANGRY:
        angryCount.value++;
        break;
    }

    currentReaction.value = newReaction;
    hasReacted.value = true;
  }
}

function initializeReactions() {
  const userReaction = props.content.reactions.find((x) => x.userId === userProfileStore.user.id);
  if (userReaction) {
    currentReaction.value = userReaction.reaction;
    hasReacted.value = true;
  } else {
    currentReaction.value = null;
    hasReacted.value = false;
  }

  likeCount.value = props.content.reactions.filter((x) => x.reaction === REACTIONS.LIKE).length;
  dislikeCount.value = props.content.reactions.filter((x) => x.reaction === REACTIONS.DISLIKE).length;
  loveCount.value = props.content.reactions.filter((x) => x.reaction === REACTIONS.LOVE).length;
  hahaCount.value = props.content.reactions.filter((x) => x.reaction === REACTIONS.HAHA).length;
  wowCount.value = props.content.reactions.filter((x) => x.reaction === REACTIONS.WOW).length;
  sadCount.value = props.content.reactions.filter((x) => x.reaction === REACTIONS.SAD).length;
  angryCount.value = props.content.reactions.filter((x) => x.reaction === REACTIONS.ANGRY).length;
}

function showReactions() {
  clearTimeout(hideTimeout.value);
  menuVisible.value = true;
}

function hideReactions() {
  hideTimeout.value = setTimeout(() => {
    menuVisible.value = false;
  }, 250);
}

function onTouchStart() {
  touchTimeout.value = setTimeout(() => {
    menuVisible.value = true; 
  }, 250); 
}
function onTouchEnd() {
  clearTimeout(touchTimeout.value);
}

function onMouseUp() {
  clearTimeout(holdTimeout.value);
  hideReactions();
}

function onMouseOver() {
  if (!isMobileDevice()) {
    showReactions();
  }
}

function onMouseLeave() {
  if (!isMobileDevice()) {
    hideReactions();
  }
}

function keepReactionMenuOpen(){
  clearTimeout(hideTimeout.value);
}

function isMobileDevice() {
  return window.innerWidth <= 800;
}
</script>

<template>
  <div style="position: relative; display: inline-block;">
    <v-menu
        class="reaction-card"
        v-model="menuVisible"
        offset-y
        :close-on-content-click="false"
        transition="scale-transition"
        :attach="$el"
    >
      <template v-slot:activator="{ on, attrs }">
        <v-btn
            v-bind="attrs"
            :on="on"
            icon="true"
            variant="plain"
            @touchstart="onTouchStart"
            @touchend="onTouchEnd"
            @mouseup="onMouseUp"
            @mouseover="onMouseOver"
            @mouseleave="onMouseLeave"
            @click="reactToContent(REACTIONS.LIKE)"
        >
          <v-icon :class="{'active-icon': currentReaction === REACTIONS.LIKE}">mdi-thumb-up-outline</v-icon>
          {{ likeCount }}
        </v-btn>
      </template>
      <v-card
          class="reaction-card"
          @mouseover="keepReactionMenuOpen"
          @mouseleave="hideReactions"
      >
          <v-btn 
              variant="plain" 
              @click="reactToContent(REACTIONS.DISLIKE)"
          >
            <v-icon :class="{'active-icon': currentReaction === REACTIONS.DISLIKE}">mdi-thumb-down-outline</v-icon>
          </v-btn>
        
          <v-btn 
              variant="plain" 
              @click="reactToContent(REACTIONS.LOVE)"
          >
            <v-icon :class="{'active-icon': currentReaction === REACTIONS.LOVE}">mdi-heart-outline</v-icon>
            {{ loveCount }}
          </v-btn>
        
          <v-btn 
              variant="plain" 
              @click="reactToContent(REACTIONS.HAHA)"
          >
            <v-icon :class="{'active-icon': currentReaction === REACTIONS.HAHA}">mdi-emoticon-excited-outline</v-icon>
            {{ hahaCount }}
          </v-btn>
        
          <v-btn
              variant="plain"
              @click="reactToContent(REACTIONS.WOW)"
          >
            <v-icon :class="{'active-icon': currentReaction === REACTIONS.WOW}">mdi-emoticon-happy-outline</v-icon>
            {{ wowCount }}
          </v-btn>
        
          <v-btn
              variant="plain"
              @click="reactToContent(REACTIONS.SAD)"
          >
            <v-icon :class="{'active-icon': currentReaction === REACTIONS.SAD}">mdi-emoticon-sad-outline</v-icon>
            {{ sadCount }}
          </v-btn>
        
          <v-btn
              variant="plain"
              @click="reactToContent(REACTIONS.ANGRY)"
          >
            <v-icon :class="{'active-icon': currentReaction === REACTIONS.ANGRY}">mdi-emoticon-angry-outline</v-icon>
            {{ angryCount }}
          </v-btn>
      </v-card>
    </v-menu>
    <must-be-logged v-model="loginModal" message="Vous devez être connecté pour réagir."></must-be-logged>
  </div>
</template>

<style scoped>
.reaction-card {
  display: flex;
  justify-content: space-around;
  padding: 8px;
  margin-top: -35px;
  margin-left: 100px;
}

.active-icon {
  color: blue;
  stroke: blue;
}
</style>
