import React, { useState } from "react";
import { Dialog, Group, Stack, Text } from "@mantine/core";
import { useClickOutside } from "@mantine/hooks";
import { useAtom } from "jotai";
import {
  activeCommentIdAtom,
  draftCommentIdAtom,
  showCommentPopupAtom,
  showReadOnlyCommentPopupAtom,
  readOnlyCommentDataAtom,
} from "@/features/comment/atoms/comment-atom";
import CommentEditor from "@/features/comment/components/comment-editor";
import CommentActions from "@/features/comment/components/comment-actions";
import { currentUserAtom } from "@/features/user/atoms/current-user-atom";
import { useCreateCommentMutation } from "@/features/comment/queries/comment-query";
import { asideStateAtom } from "@/components/layouts/global/hooks/atoms/sidebar-atom";
import { useEditor } from "@tiptap/react";
import { CustomAvatar } from "@/components/ui/custom-avatar.tsx";
import { useTranslation } from "react-i18next";

interface CommentDialogProps {
  editor: ReturnType<typeof useEditor>;
  pageId: string;
  readOnly?: boolean;
}

function CommentDialog({ editor, pageId, readOnly }: CommentDialogProps) {
  const { t } = useTranslation();
  const [comment, setComment] = useState("");
  const [, setShowCommentPopup] = useAtom(showCommentPopupAtom);
  const [, setShowReadOnlyCommentPopup] = useAtom(showReadOnlyCommentPopupAtom);
  const [readOnlyCommentData, setReadOnlyCommentData] = useAtom(readOnlyCommentDataAtom);
  const [, setActiveCommentId] = useAtom(activeCommentIdAtom);
  const [draftCommentId, setDraftCommentId] = useAtom(draftCommentIdAtom);
  const [currentUser] = useAtom(currentUserAtom);
  const [, setAsideState] = useAtom(asideStateAtom);
  const useClickOutsideRef = useClickOutside(() => {
    if (document.querySelector("#mention")) return;
    handleDialogClose();
  });
  const createCommentMutation = useCreateCommentMutation();
  const isPending = createCommentMutation.isPending;

  const handleDialogClose = () => {
    if (readOnly) {
      setShowReadOnlyCommentPopup(false);
      // @ts-ignore
      setReadOnlyCommentData(null);
    } else {
      setShowCommentPopup(false);
      editor.chain().focus().unsetCommentDecoration().run();
    }
  };

  const getSelectedText = () => {
    const { from, to } = editor.state.selection;
    return editor.state.doc.textBetween(from, to);
  };

  const handleAddComment = async () => {
    if (readOnly) {
      await handleAddReadOnlyComment();
      return;
    }

    try {
      const selectedText = getSelectedText();
      const commentData = {
        pageId: pageId,
        content: JSON.stringify(comment),
        selection: selectedText,
        type: "inline",
      };

      const createdComment =
        await createCommentMutation.mutateAsync(commentData);
      editor
        .chain()
        .setComment(createdComment.id)
        .unsetCommentDecoration()
        .run();
      setActiveCommentId(createdComment.id);

      editor.commands.setTextSelection({ from: editor.view.state.selection.from, to: editor.view.state.selection.from });

      setAsideState({ tab: "comments", isAsideOpen: true });
      setTimeout(() => {
        const selector = `div[data-comment-id="${createdComment.id}"]`;
        const commentElement = document.querySelector(selector);
        commentElement?.scrollIntoView({ behavior: "smooth", block: "center" });

        editor.view.dispatch(
          editor.state.tr.scrollIntoView()
        );
      }, 400);

    } finally {
      setShowCommentPopup(false);
      setDraftCommentId("");
    }
  };

  const handleAddReadOnlyComment = async () => {
    if (!readOnlyCommentData) return;

    try {
      const createdComment = await createCommentMutation.mutateAsync({
        pageId,
        content: JSON.stringify(comment),
        selection: readOnlyCommentData.selectedText,
        type: "inline",
        yjsSelection: readOnlyCommentData.yjsSelection,
      });

      setActiveCommentId(createdComment.id);
      setAsideState({ tab: "comments", isAsideOpen: true });

      setTimeout(() => {
        const selector = `div[data-comment-id="${createdComment.id}"]`;
        const commentElement = document.querySelector(selector);
        commentElement?.scrollIntoView({ behavior: "smooth", block: "center" });
      }, 400);
    } finally {
      setShowReadOnlyCommentPopup(false);
      // @ts-ignore
      setReadOnlyCommentData(null);
    }
  };

  const handleCommentEditorChange = (newContent: any) => {
    setComment(newContent);
  };

  return (
    <Dialog
      opened={true}
      onClose={handleDialogClose}
      ref={useClickOutsideRef}
      size="lg"
      radius="md"
      w={300}
      zIndex={180}
      position={{ bottom: 500, right: 50 }}
      withCloseButton
      withBorder
      data-comment-dialog
      aria-label={t("Add comment")}
    >
      <Stack gap={2}>
        <Group>
          <CustomAvatar
            size="sm"
            avatarUrl={currentUser.user.avatarUrl}
            name={currentUser.user.name}
          />
          <div style={{ flex: 1 }}>
            <Group justify="space-between" wrap="nowrap">
              <Text size="sm" fw={500} lineClamp={1}>
                {currentUser.user.name}
              </Text>
            </Group>
          </div>
        </Group>

        <CommentEditor
          onUpdate={handleCommentEditorChange}
          onSave={handleAddComment}
          placeholder={t("Write a comment")}
          editable={true}
          autofocus={true}
        />
        <CommentActions onSave={handleAddComment} isLoading={isPending} />
      </Stack>
    </Dialog>
  );
}

export default CommentDialog;
