<template>
  <aside id="comments-container" aria-labelledby="comments-label">
    <h2 id="comments-label" class="sr-only">Commentaires</h2>
    <div class="comments | flow" :class="{ empty: comments.length === 0 }">
      <template v-if="comments">
        <template v-if="!openedComment">
          <Comment
            v-for="(comment, commentIndex) in sortedComments"
            :comment="comment"
            :commentIndex="comments.length - commentIndex"
            :key="comment.id"
            @click="openedComment = comment"
            @update:file="changeFile"
            @close:comment="closeComment"
          />
        </template>
        <template v-else>
          <button
            class="btn | justify-start w-full | bg-white-10 text-white | px-8"
            data-icon="chevron-single-left"
            @click="
              openedComment = null;
              isAddOpen = false;
            "
          >
            <span>Retour à la liste</span>
          </button>
          <Comment
            :comment="openedComment"
            data-opened="true"
            @update:file="changeFile"
            @close:comment="closeComment"
          />
          <div v-if="sortedReplies.length > 0" class="replies | flow">
            <Comment
              v-for="(reply, commentIndex) in sortedReplies"
              :comment="reply"
              :commentIndex="sortedReplies.length - commentIndex"
              :key="reply.id"
              @update:file="changeFile"
              @close:comment="closeComment"
            />
          </div>
        </template>
      </template>
      <template v-else> état aucun commentaire </template>
    </div>
    <button
      v-if="!openedComment && !isAddOpen"
      id="create-comment"
      class="btn btn--white-20 | w-full"
      @click="toggleCommentPositionMode(true)"
    >
      Ajouter un commentaire
    </button>
    <button
      v-else-if="openedComment && !isAddOpen"
      id="reply-comment"
      class="btn btn--white-20 | justify-start w-full | text-white-50"
      @click="isAddOpen = true"
    >
      Répondre…
    </button>
    <!-- TODO: afficher #new-comment une fois le bouton Ajouter un commentaire cliqué -->
    <div
      hidden
      id="new-comment"
      class="bg-primary | text-sm text-white | rounded-lg | p-12"
    >
      <p class="flex justify-start | mb-12" data-icon="comment">
        <strong>Nouveau commentaire</strong>
      </p>
      <p>
        Dans la zone du contenu, cliquez où vous souhaitez positionner le
        commentaire
      </p>
    </div>
    <form
      v-if="isAddOpen"
      action=""
      method="post"
      class="flow | bg-white-20 | p-12 | rounded-xl"
      @submit="handleSubmit"
    >
      <label class="sr-only" for="comment">Votre commentaire</label>
      <textarea
        name="comment"
        id="comment"
        placeholder="Ajouter un commentaire…"
        rows="5"
        class="text-sm | rounded-lg bg-black p-12"
        v-model="newCommentText"
      ></textarea>
      <footer class="flex">
        <input type="submit" class="btn btn--tranparent" />
        <button class="btn btn--white-10" @click="isAddOpen = false">
          Annuler
        </button>
      </footer>
    </form>
  </aside>
</template>

<script setup>
import dayjs from "dayjs";
import "dayjs/locale/fr";
import uniqid from "uniqid";
import { watch, ref } from "vue";
import { useUserStore } from "../../stores/user";
import { usePageStore } from "../../stores/page";
import { useApiStore } from "../../stores/api";
import Comment from "./Comment.vue";

dayjs.locale("fr");

const { currentPageIndex, file, comments } = defineProps({
  currentPageIndex: Number,
  file: Object,
  comments: Array,
});

const { user } = useUserStore();
const { page } = usePageStore();
const api = useApiStore();

const openedComment = ref(null);

const newCommentPageIndex = ref(null);
const newCommentPosition = ref(null);
const newCommentText = ref("");
const isAddOpen = ref(false);
const emits = defineEmits(["update:file"]);

const sortedComments = ref(comments.reverse());
const sortedReplies = ref(null);

watch(openedComment, (newVal) => {
  sortedReplies.value = newVal ? newVal.replies.slice().reverse() : null;
});

watch(
  () => comments,
  (newVal) => {
    sortedComments.value = newVal.reverse();
  }
);

const viewContainer = document.querySelector(".vpv-pages-inner-container");

// Functions
function handleSubmit(event) {
  event.preventDefault();
  const date = dayjs().format();
  const newComment = {
    pageUri: page.uri + "/client-brief",
    fileName: file.name,
    userUuid: user.uuid,
    text: newCommentText.value,
    date,
    position:
      {
        pageIndex: newCommentPageIndex.value,
        x: newCommentPosition.value.x,
        y: newCommentPosition.value.y,
      } ?? false,
    id: uniqid(),
  };
  if (openedComment.value) {
    replyComment(newComment);
  } else {
    console.log(newComment);
    addComment(newComment);
  }
}

async function replyComment(newComment) {
  newComment.parentId = openedComment.value.id;
  const newFile = await api.replyComment(newComment);
  newCommentText.value = "";
  isAddOpen.value = false;
  openedComment.value = newFile.comments.find(
    (item) => item.id === openedComment.value.id
  );
  emits("update:file", newFile);
}

async function addComment(newComment) {
  const newFile = await api.addComment(newComment);
  newCommentText.value = "";
  isAddOpen.value = false;
  emits("update:file", newFile);
}

function changeFile(newFile) {
  console.log(newFile);
  emits("update:file", newFile);
}

function closeComment() {
  openedComment.value = null;
}

function toggleCommentPositionMode(enable) {
  if (enable) {
    viewContainer.classList.add("waiting-comment");
    viewContainer.addEventListener("click", handleCommentPositionClick);
  } else {
    viewContainer.classList.remove("waiting-comment");
    viewContainer.removeEventListener("click", handleCommentPositionClick);
  }
}

function handleCommentPositionClick(event) {
  const pageContainer = event.target.closest(".page-inner-container");
  if (!pageContainer) return;

  const pageLabel = pageContainer
    .closest(".vpv-page-inner-container")
    .getAttribute("aria-label");
  const pageIndex = pageLabel.charAt(pageLabel.length - 1);

  newCommentPageIndex.value = parseInt(pageIndex);

  const viewRect = viewContainer.getBoundingClientRect();
  const pageRect = pageContainer.getBoundingClientRect();
  const pageScroll = viewRect.top - pageRect.top;

  const mouseTop = event.clientY;
  const y = mouseTop - viewRect.top + pageScroll;
  const x = event.clientX - pageRect.left;

  newCommentPosition.value = {
    x,
    y,
  };
  isAddOpen.value = true;
  toggleCommentPositionMode(false);
}
</script>

<style>
/* Comments */
#toggle-comments {
  position: absolute;
  right: var(--space-16);
  bottom: var(--space-16);
  padding: 0.625rem;
}
#comments-container {
  background-color: black;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 4.5rem;
  width: var(--dialog-comments-w);
  padding: var(--space-24) var(--space-32);
}
.comments {
  overflow-y: auto;
  height: calc(100% - 3.5rem);
  margin-bottom: 1rem;
  margin-right: -2rem;
  padding-right: 2rem;
}
.comments.empty::after {
  content: "Partagez vos idées en ajoutant des commentaires";
  height: 100%;
  display: grid;
  place-items: center;
  text-align: center;
  max-width: 24ch;
  margin: auto;
  font-size: var(--text-sm);
  color: var(--color-grey-400);
  background-image: var(--icon-comment);
  background-position: center;
  background-repeat: no-repeat;
}
.comments.empty::before {
  --icon-size: 1.25rem;
  --icon-color: var(--color-white);
  content: "";
  display: block;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, calc(-50% - 4.5rem));
  width: var(--icon-size);
  height: var(--icon-size);
  background: var(--icon-color, currentColor);
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: var(--icon-size);
  mask-image: var(--icon-comment);
}
#new-comment {
  position: absolute;
  bottom: var(--space-24);
  left: var(--space-32);
  right: var(--space-32);
}
#new-comment [data-icon] {
  --column-gap: var(--space-12);
  font-weight: 500;
}
#comments-container form {
  --flow-space: 0.5rem;
  flex-direction: column;
  position: -webkit-sticky;
  position: sticky;
  bottom: 5.5rem;
}
#comments-container textarea {
  position: sticky;
  bottom: 0;
  margin: 0;
  resize: none;
  background: none;
  padding: 0;
  color: var(--color-white);
}
#comments-container textarea:focus {
  outline: none;
}
::placeholder {
  color: var(--color-white-50);
}
#comments-container form footer {
  gap: var(--space-12);
}
#comments-container form footer > * {
  flex-grow: 1;
}

.vpv-pages-inner-container.waiting-comment .page-inner-container,
.vpv-pages-inner-container.waiting-comment .vpv-text-layer-text,
.vpv-pages-inner-container.waiting-comment .vpv-text-layer-wrapper {
  cursor: cell !important;
}
</style>
