<template>
  <article
    :id="`comment-${comment.id}`"
    class="comment | flow"
    :data-status="getStatus"
    @click="handleClick()"
    @mouseenter="hightlightCorrespondingMarker()"
    @mouseleave="unhightlightCorrespondingMarker()"
    ref="comment-node"
  >
    <header>
      <p>
        <strong>{{ comment.author.name ?? comment.author.email }}</strong>
        <template v-if="commentIndex">
          <span class="comment__id">#{{ commentIndex }}</span>
        </template>
        <span v-if="comment.position.pageIndex" class="comment__page">
          • Page {{ comment.position.pageIndex }}
        </span>
        <time
          class="comment__date"
          :datetime="dayjs(comment.date).format('YYYY-MM-DD')"
          >{{ formatDate(comment.date) }}</time
        >
      </p>
    </header>

    <p v-if="!comment.isEditMode" class="comment__body">
      {{ comment.text }}
    </p>

    <textarea
      v-else
      class="comment__body"
      v-model="draftText"
      :rows="Math.ceil(draftText.length / 32)"
      ref="editField"
    ></textarea>

    <footer v-if="!comment.isEditMode" class="comment__replies">
      <p v-if="comment.replies?.length > 0">
        {{ comment.replies.length }} réponse{{
          comment.replies.length > 1 ? 's' : ''
        }}
      </p>
      <div
        v-if="userStore.canEditComment(comment)"
        class="comment__ctas | mt-8"
      >
        <button
          class="btn btn--transparent btn--icon btn--sm"
          data-icon="edit"
          @click="editComment($event)"
        >
          <span class="sr-only">Éditer</span>
        </button>
        <button
          class="btn btn--transparent btn--icon btn--sm"
          data-icon="delete"
          @click="deleteComment($event)"
        >
          <span class="sr-only">Supprimer</span>
        </button>
      </div>
    </footer>

    <footer v-else class="comment__edit-ctas">
      <input
        type="submit"
        class="btn btn--tranparent"
        value="Sauvegarder"
        @click="saveEditedComment($event)"
      />
      <button class="btn btn--white-10" @click="cancelEditComment($event)">
        Annuler
      </button>
    </footer>
  </article>
</template>

<script setup>
import dayjs from 'dayjs';
import 'dayjs/locale/fr';
import { useUserStore } from '../../stores/user';
import { useApiStore } from '../../stores/api';
import { useDialogStore } from '../../stores/dialog';
import { computed, onMounted, ref, useTemplateRef } from 'vue';
import { storeToRefs } from 'pinia';
import { usePageStore } from '../../stores/page';
import { useRoute } from 'vue-router';

dayjs.locale('fr');

const { comment, commentIndex } = defineProps({
  comment: Object,
  commentIndex: Number,
});

const emits = defineEmits(['update:file', 'close:comment']);

const route = useRoute();
const userStore = useUserStore();
const api = useApiStore();
const dialog = useDialogStore();
const { activeTracks, openedComment } = storeToRefs(useDialogStore());
const draftText = ref(comment.text);
const editField = ref(null);
const commentNode = useTemplateRef('comment-node');
const { page } = storeToRefs(usePageStore());
let correspondingMarker = null;

//  Functions
const getStatus = computed(() => {
  const correspondingNotification = userStore.notifications.find(
    (notification) => notification.id === comment.id
  );
  if (correspondingNotification && !correspondingNotification.isRead) {
    return 'unread';
  }
  return undefined;
});

function formatDate() {
  const todayNumber = parseInt(dayjs().format('YYMMD'));
  const dateNumber = parseInt(dayjs(comment.date).format('YYMMD'));

  if (dateNumber === todayNumber) {
    return "Aujourd'hui";
  }

  if (dateNumber === todayNumber - 1) {
    return 'hier';
  }

  return dayjs(comment.date).format('D MMM YY');
}

function closeAddField() {
  isAddOpen.value = false;
  newCommentText.value = '';
}

function handleClick() {
  read();
  scrollTo();
}

async function read() {
  if (getStatus.value !== 'unread') return;
  try {
    const newNotification = await api.readNotification(
      comment.id,
      page.value.uri
    );
  } catch (error) {
    console.log('Erreur lors de la lecture de la notification : ', error);
  }
}

function scrollTo() {
  const correspondingMarker = document.querySelector(
    `.comment-marker[href="#comment-${comment.id}"]`
  );
  if (!correspondingMarker) return;
  correspondingMarker.scrollIntoView();
}

async function deleteComment(event) {
  event.stopPropagation();
  const newFile = await api.deleteComment(comment);

  // If there is an active track, we are not in PDF mode with a single file.
  // Thus, it's not the opened file that should be updated
  // but the corresponding file in the active track.
  if (activeTracks.value?.length > 0) {
    activeTracks.value[0].files = activeTracks.value[0].files.map((file) => {
      if (file.uuid !== newFile.uuid) return file;
      return newFile;
    });
  } else {
    dialog.updateFile(newFile);
  }
  if (comment.type === 'comment-reply') {
    emits('close:comment');
  }
}

function saveEditedComment(event) {
  event.stopImmediatePropagation();
  comment.text = draftText.value;
  comment.date = dayjs().format();
  api.updateComment(comment);
  comment.isEditMode = false;
}

function cancelEditComment(event) {
  event.stopImmediatePropagation();
  comment.isEditMode = false;
  draftText.value = comment.text;
}

function editComment(event) {
  comment.isEditMode = true;
  setTimeout(() => {
    editField.value.focus();
  }, 100);
}

function hightlightCorrespondingMarker() {
  if (comment.type === 'comment-reply') return;

  const correspondingMarker = document.querySelector(
    `.comment-marker[href="#comment-${comment.id}"]`
  );
  if (!correspondingMarker) return;

  commentNode.value.classList.add('highlight');
  correspondingMarker.classList.add('active');
  correspondingMarker.classList.add('big');
}
function unhightlightCorrespondingMarker() {
  if (comment.type === 'comment-reply') return;

  const correspondingMarker = document.querySelector(
    `.comment-marker[href="#comment-${comment.id}"]`
  );
  if (!correspondingMarker) return;
  if (openedComment.value) return;

  commentNode.value.classList.remove('highlight');
  correspondingMarker.classList.remove('active');
  correspondingMarker.classList.remove('big');
}
</script>
