import { unixToDate, sinceUnixDate } from "#/api/utils";
import { useEffect, useState } from "react";
import { ENDPOINTS } from "#/api/config";
import { Button, Dropdown } from "flowbite-react";
import Link from "next/link";
import { CommentsAddModal } from "./Comments.Add";
import { CommentsEditModal } from "./Comments.Edit";
import { useUserStore } from "#/store/auth";
import Image from "next/image";

export const CommentsComment = (props: {
  release_id: number;
  profile: { login: string; avatar: string; id: number };
  comment: {
    id: number;
    timestamp: number;
    message: string;
    reply_count: number;
    likes_count: number;
    vote: number;
    isSpoiler: boolean;
    isEdited: boolean;
    isDeleted: boolean;
  };
  isSubComment?: boolean;
  token: string | null;
  isReplying?: boolean;
  parentComment?: any;
  setShouldRender?: (shouldRender: boolean) => void;
  setCommentSend?: (commentSend: boolean) => void;
  type?: "release" | "collection";
}) => {
  const [replies, setReplies] = useState([]);
  const [likes, setLikes] = useState(props.comment.likes_count);
  const [vote, setVote] = useState(props.comment.vote);
  const [isAddCommentsOpen, setIsAddCommentsOpen] = useState(false);
  const [isEditCommentsOpen, setIsEditCommentsOpen] = useState(false);
  const [isHidden, setIsHidden] = useState(
    !props.isReplying &&
      (props.comment.isSpoiler || props.comment.likes_count < -5)
  );
  const user: any = useUserStore((state) => state.user);

  const [shouldRender, setShouldRender] = useState(true);
  const [commentSend, setCommentSend] = useState(false);

  let parentCommentId: number | null = null;
  if (props.parentComment) {
    parentCommentId = props.parentComment.id;
  }

  async function _deleteComment() {
    if (props.token) {
      let url;
      if (props.type == "collection") {
        url = `${ENDPOINTS.collection.base}/comment/delete/${props.comment.id}?token=${props.token}`;
      } else {
        url = `${ENDPOINTS.release.info}/comment/delete/${props.comment.id}?token=${props.token}`;
      }
      await fetch(url);

      if (props.setShouldRender && props.setCommentSend) {
        props.setShouldRender(true);
        props.setCommentSend(true);
      }
    }
  }

  useEffect(() => {
    async function _fetchReplies() {
      setReplies([]);
      let url;
      if (props.type == "collection") {
        url = `${ENDPOINTS.collection.base}/comment/replies/${
          parentCommentId || props.comment.id
        }/0?sort=2`;
      } else {
        url = `${ENDPOINTS.release.info}/comment/replies/${
          parentCommentId || props.comment.id
        }/0?sort=2`;
      }

      if (props.token) {
        url += `&token=${props.token}`;
      }
      await fetch(url)
        .then((res) => res.json())
        .then((data) => {
          setReplies(data.content);
        });
    }
    if (
      !props.isSubComment &&
      !props.isReplying &&
      shouldRender &&
      (commentSend || props.comment.reply_count > 0)
    ) {
      _fetchReplies();
      setShouldRender(false);
      setCommentSend(false);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [commentSend]);

  async function _sendVote(action: number) {
    if (props.token) {
      let url;

      if (props.type == "collection") {
        url = `${ENDPOINTS.collection.base}/comment/vote/${props.comment.id}/${action}?token=${props.token}`;
      } else {
        url = `${ENDPOINTS.release.info}/comment/vote/${props.comment.id}/${action}?token=${props.token}`;
      }
      fetch(url);
    }
  }

  // TODO: make it readable
  function _updateVote(action: string) {
    if (action === "like" && vote == 0) {
      setVote(2);
      setLikes(likes + 1);
      _sendVote(2);
    } else if (action === "dislike" && vote == 0) {
      setVote(1);
      setLikes(likes - 1);
      _sendVote(1);
    } else if (action === "like" && vote == 1) {
      setVote(2);
      setLikes(likes + 2);
      _sendVote(2);
    } else if (action === "dislike" && vote == 2) {
      setVote(1);
      setLikes(likes - 2);
      _sendVote(1);
    } else {
      _sendVote(vote);
      setVote(0);
      if (action === "dislike" && vote == 1) {
        setLikes(likes + 1);
      } else if (action === "like" && vote == 2) {
        setLikes(likes - 1);
      }
    }
  }

  return (
    <>
      <article
        className={`${
          !props.isSubComment || props.type == "collection" ? "p-6" : "pt-4"
        } text-sm bg-gray-100 rounded-lg sm:text-base dark:bg-gray-900`}
      >
        <footer className="flex items-center justify-between mb-2">
          <div className="flex flex-col items-start gap-1 sm:items-center sm:flex-row">
            <Link
              href={`/profile/${props.profile.id}`}
              className="inline-flex items-center mr-3 text-sm font-semibold text-gray-900 dark:text-white hover:underline"
            >
              <Image
                className="w-6 h-6 mr-2 rounded-full"
                width={24}
                height={24}
                src={props.profile.avatar}
                alt=""
              />
              {props.profile.login}
            </Link>
            <p className="text-sm text-gray-600 dark:text-gray-400">
              <time
                dateTime={props.comment.timestamp.toString()}
                title={unixToDate(props.comment.timestamp, "full")}
              >
                {sinceUnixDate(props.comment.timestamp)}
              </time>
            </p>
          </div>
          {user && props.profile.id == user.id && (
            <Dropdown
              label=""
              dismissOnClick={false}
              renderTrigger={() => (
                <span className="w-6 h-6 bg-gray-400 iconify mdi--more-horiz hover:bg-gray-800 active:bg-gray-800"></span>
              )}
            >
              <Dropdown.Item onClick={() => setIsEditCommentsOpen(true)}>
                Редактировать
              </Dropdown.Item>
              <Dropdown.Item onClick={() => _deleteComment()}>
                Удалить
              </Dropdown.Item>
            </Dropdown>
          )}
        </footer>
        <div className="relative flex items-center py-2">
          <p className="text-gray-800 whitespace-pre-wrap dark:text-gray-400">
            {!props.comment.isDeleted
              ? props.comment.message
              : "Комментарий был удалён."}
          </p>
          {isHidden && (
            <button
              className="absolute top-0 bottom-0 left-0 right-0"
              onClick={() => setIsHidden(false)}
            >
              <div className="min-w-full min-h-full px-2 py-1.5 rounded-md bg-black text-white bg-opacity-50 backdrop-blur-[8px] flex flex-col justify-center items-center">
                <p>
                  {props.comment.likes_count < -5
                    ? "У комментария слишком низкий рейтинг."
                    : "Данный комментарий может содержать спойлер."}
                </p>
                <p className="font-bold">Нажмите, чтобы прочитать</p>
              </div>
            </button>
          )}
        </div>
        {!props.isReplying && !props.comment.isDeleted && (
          <div
            className={`flex items-center justify-between space-x-4 ${
              isHidden ? "mt-4" : ""
            }`}
          >
            {props.token ? (
              <button
                type="button"
                className="flex items-center text-sm font-medium text-gray-500 hover:underline dark:text-gray-400"
                onClick={() => setIsAddCommentsOpen(true)}
              >
                <svg
                  className="mr-1.5 w-3.5 h-3.5"
                  aria-hidden="true"
                  xmlns="http://www.w3.org/2000/svg"
                  fill="none"
                  viewBox="0 0 20 18"
                >
                  <path
                    stroke="currentColor"
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth="2"
                    d="M5 5h5M5 8h2m6-3h2m-5 3h6m2-7H2a1 1 0 0 0-1 1v9a1 1 0 0 0 1 1h3v5l5-5h8a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1Z"
                  />
                </svg>
                Ответить
              </button>
            ) : (
              <span></span>
            )}
            <div className="flex items-center">
              <Button
                color="inline"
                onClick={() => {
                  _updateVote("dislike");
                }}
                disabled={!props.token}
              >
                <span
                  className={`w-6 h-6 iconify mdi--dislike ${
                    vote == 1
                      ? "text-red-500 dark:text-red-400"
                      : "text-gray-500 dark:text-gray-400"
                  }`}
                ></span>
              </Button>
              <p
                className={`text-sm font-medium ${
                  likes > 0
                    ? "text-green-500 dark:text-green-400"
                    : likes < 0
                    ? "text-red-500 dark:text-red-400"
                    : "text-gray-500 dark:text-gray-400"
                }`}
              >
                {likes}
              </p>
              <Button
                color="inline"
                onClick={() => {
                  _updateVote("like");
                }}
                disabled={!props.token}
              >
                <span
                  className={`w-6 h-6 iconify mdi--like ${
                    vote == 2
                      ? "text-green-500 dark:text-green-400"
                      : "text-gray-500 dark:text-gray-400"
                  }`}
                ></span>
              </Button>
            </div>
          </div>
        )}
        {replies.length > 0 &&
          replies.map((comment: any) => (
            <CommentsComment
              key={comment.id}
              release_id={props.release_id}
              profile={comment.profile}
              comment={{
                id: comment.id,
                timestamp: comment.timestamp,
                message: comment.message,
                reply_count: comment.reply_count,
                likes_count: comment.likes_count,
                vote: comment.vote,
                isSpoiler: comment.is_spoiler,
                isEdited: comment.is_edited,
                isDeleted: comment.is_deleted,
              }}
              isSubComment={true}
              token={props.token}
              parentComment={props.parentComment || props.comment}
              setShouldRender={props.setShouldRender || setShouldRender}
              setCommentSend={props.setCommentSend || setCommentSend}
            />
          ))}
      </article>
      <CommentsAddModal
        isOpen={isAddCommentsOpen}
        setIsOpen={setIsAddCommentsOpen}
        release_id={props.release_id}
        token={props.token}
        isReply={true}
        parentComment={props.parentComment || props.comment}
        parentProfile={props.profile}
        setShouldRender={props.setShouldRender || setShouldRender}
        setCommentSend={props.setCommentSend || setCommentSend}
        type={props.type}
      />
      {props.token && (
        <CommentsEditModal
          isOpen={isEditCommentsOpen}
          setIsOpen={setIsEditCommentsOpen}
          token={props.token}
          parentComment={props.comment}
          setShouldRender={props.setShouldRender || setShouldRender}
          setCommentSend={props.setCommentSend || setCommentSend}
          type={props.type}
        />
      )}
    </>
  );
};