import React, { useEffect, useRef, useState } from "react";
import { CloseIcon, KebabIcon } from "../../icons/ExportCommonIcons";
import Messages from "./Messages";
import { ExpandIcon } from "../../icons/SimulationIcons";
import { adjustHeight } from "./function/textAreaHeightAdjust";
import { useParams } from "react-router-dom";
import { useSelectedComment, useSocketStore } from "../../../store/builder/store";
import { useCommentStore } from "../../../store/collaboration/useCommentStore";
import { getUserData } from "../../../functions/getUserData";
import ThreadSocketResponsesDev from "../../../modules/collaboration/socket/threadSocketResponses.dev";
import { addCommentsApi } from "../../../services/factoryBuilder/comments/addCommentsApi";
import { deleteThreadApi } from "../../../services/factoryBuilder/comments/deleteThreadApi";
import { createThreadApi } from "../../../services/factoryBuilder/comments/createThreadApi";
import { getRelativeTime } from "./function/getRelativeTime";
import { useVersionContext } from "../../../modules/builder/version/versionContext";

const ThreadChat: React.FC = () => {
  const { userId, organization } = getUserData();
  const [openThreadOptions, setOpenThreadOptions] = useState(false);
  const [inputActive, setInputActive] = useState(false);
  const [value, setValue] = useState<string>("");
  const { addComment, removeReply, removeComment, addReply, comments } = useCommentStore();
  const { selectedComment, setSelectedComment, setCommentPositionState, commentPositionState, position2Dstate } = useSelectedComment()
  const [mode, setMode] = useState<'create' | 'edit' | null>('create');
  const [isEditable, setIsEditable] = useState(false);
  const [editedThread, setEditedThread] = useState(false);
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const wrapperRef = useRef<HTMLDivElement>(null);
  const [messages, setMessages] = useState<Reply[]>([])
  const { projectId } = useParams();
  const [dragging, setDragging] = useState(false);
  const [selectedDiv, setSelectedDiv] = useState(true);
  const [dragOffset, setDragOffset] = useState({ x: 0, y: 0 });
  const [position, setPosition] = useState({ x: position2Dstate.x, y: position2Dstate.y });
  const { threadSocket } = useSocketStore();
  const modeRef = useRef<'create' | 'edit' | null>(null);
  const messagesRef = useRef<HTMLDivElement>(null);
  const { selectedVersionStore } = useVersionContext();
  const { selectedVersion } = selectedVersionStore();

  useEffect(() => {
    modeRef.current = mode;
  }, [mode]);

  useEffect(() => {
    if (comments.length > 0 && selectedComment) {

      const allMessages = comments
        .flatMap((val: any) =>
          val?.threadId === selectedComment?.threadId ? val.comments : []
        )
        .map((c) => {
          return {
            replyId: c._id ?? c.replyId,
            creatorId: c.creatorId || c.userId,
            createdAt: c.createdAt,
            lastUpdatedAt: "1 hr ago",
            comment: c.comment,
            _id: c._id ?? c.replyId,
          };
        });

      setMessages(allMessages);

    }

  }, [])

  useEffect(() => {
    if (textareaRef.current) adjustHeight(textareaRef.current);
  }, [value]);

  const clamp = (val: number, min: number, max: number) => {
    return Math.min(Math.max(val, min), max);
  };

  const handlePointerDown = (event: React.PointerEvent<HTMLDivElement>) => {
    if (event.button !== 0) return;
    // Avoid dragging if a button, icon, textarea etc. was clicked
    const target = event.target as HTMLElement;
    if (
      target.closest("button") ||
      target.closest(".sent-button") ||
      target.closest("textarea") ||
      target.closest(".options-button") ||
      target.closest(".options-list") ||
      target.closest(".send-message-wrapper") ||
      target.closest(".options delete")
    ) {
      return;
    }

    const wrapper = wrapperRef.current;
    if (!wrapper) return;

    const rect = wrapper.getBoundingClientRect();
    const offsetX = event.clientX - rect.left;
    const offsetY = event.clientY - rect.top;

    setDragging(true);
    setDragOffset({ x: offsetX, y: offsetY });

    wrapper.setPointerCapture(event.pointerId);
  };

  const updatePosition = (
    { clientX, clientY }: { clientX: number; clientY: number },
    allowMove: boolean = true
  ) => {
    if (!allowMove || !wrapperRef.current) return;

    const container = document.getElementById("work-space-three-d-canvas");
    const wrapper = wrapperRef.current;
    if (!container || !wrapper) return;

    const containerRect = container.getBoundingClientRect();

    let newX = clientX - containerRect.left - dragOffset.x;
    let newY = clientY - containerRect.top - dragOffset.y;

    const maxX = containerRect.width - wrapper.offsetWidth;
    const maxY = containerRect.height - wrapper.offsetHeight;

    newX = clamp(newX, 0, maxX);
    newY = clamp(newY, 0, maxY);

    setPosition({ x: newX, y: newY });
  };

  const handlePointerMove = (e: { clientX: number; clientY: number }) => {
    if (dragging) updatePosition(e, true);
  };

  useEffect(() => {
    updatePosition({ clientX: position.x, clientY: position.y }, true);
  }, [selectedComment]);


  const handlePointerUp = (event: React.PointerEvent<HTMLDivElement>) => {
    if (!dragging) return;
    setDragging(false);
    const wrapper = wrapperRef.current;
    if (wrapper) wrapper.releasePointerCapture(event.pointerId);
  };

  const handleCreateComments = async (e: any) => {
    e.preventDefault();
    try {
      // const createComments = await addCommentsApi(projectId, value, selectedComment?.threadId,  selectedVersion?.versionId || "")/ 
      // if (createComments.message === 'Thread comments add Successfully' && createComments.data) {
      //     const commentData = {
      //         replyId: `${createComments.data?._id}`,
      //         creatorId: `${selectedComment?.threadId}`,
      //         createdAt: "2 hrs ago",
      //         lastUpdatedAt: "2 hrs ago",
      //         comment: value,
      //     }
      //     setMessages((prevMessages) => [
      //         ...prevMessages,
      //         commentData,
      //     ]);
      //     addReply(selectedComment?.threadId, commentData)

      // }

      if (threadSocket && mode === "create") {
        const addComment = {
          versionId: selectedVersion?.versionId || "",
          projectId,
          userId,
          comment: value,
          organization,
          threadId: selectedComment?.threadId,

        }

        threadSocket.emit("v1-Comment:add", addComment);
      }
    } catch {

    }
    setInputActive(false)
  }
  const handleDeleteThread = async () => {
    if (!projectId) return;
    try {
      // const deleteThread = await deleteThreadApi(projectId, selectedComment?.threadId, selectedVersion?.versionId || "")
      // 
      // if (deleteThread.message === "Thread deleted Successfully") {
      //     removeComment(selectedComment?.threadId)
      //     setSelectedComment([])
      // }
      console.log('threadSocket:threadChat ', threadSocket);
      if (threadSocket) {
        // projectId, userId, organization, threadId
        const deleteThread = {
          projectId,
          userId,
          organization,
          threadId: selectedComment?.threadId,
          versionId: selectedVersion?.versionId || ""
        }
        setSelectedComment(null)
        removeComment(selectedComment?.threadId)
        threadSocket.emit("v1:thread:delete", deleteThread);
      }
    }
    catch {

    }
  }

  const handleCreateThread = async (e: any) => {
    e.preventDefault();
    if (!projectId) return;

    try {
      //     try {
      // const thread = await createThreadApi(
      //   projectId,
      //   "active",
      //   commentPositionState[0].position,
      //   [0, 0, 0],
      //   value,
      //   selectedVersion?.versionId || ""
      // );
      // 
      // 

      // if (thread.message === "Thread created Successfully" && thread?.threadData) {
      //     
      //     const comment: CommentSchema = {
      //         state: 'active',
      //         threadId: thread?.threadData?._id,
      //         creatorId: userId,
      //         createdAt: getRelativeTime(thread.threadData?.createdAt),
      //         threadTitle: value,
      //         lastUpdatedAt: new Date().toISOString(),
      //         position: commentPositionState[0].position,
      //         rotation: [0, 0, 0],
      //         comments: []
      //     }
      //     addComment(comment);
      //     setCommentPositionState(null);
      //     setInputActive(false);
      //     setSelectedComment([])
      // }

      const createThread = {
        projectId,
        versionId: selectedVersion?.versionId || "",
        userId,
        organization,
        state: "active",
        position: commentPositionState.position,
        rotation: [0, 0, 0],
        threadTitle: value,
      };

      if (threadSocket) {
        console.log('createThread: ', createThread);

        setInputActive(false);
        threadSocket.emit("v1:thread:create", createThread);
      }
    } catch (err) {

    }
  };

  const scrollToBottom = () => {
    const messagesWrapper = document.querySelector(".messages-wrapper");
    if (messagesWrapper) {
      messagesWrapper.scrollTop = messagesWrapper.scrollHeight;
    }
  };

  useEffect(() => {
    if (messages.length > 0)
      scrollToBottom();
  }, [messages])

  return (
    <div
      ref={wrapperRef}
      className="thread-chat-wrapper"
      onPointerDown={handlePointerDown}
      onPointerMove={(e) => handlePointerMove({ clientX: e.clientX, clientY: e.clientY })}
      onPointerUp={handlePointerUp}
      style={{
        position: "absolute",
        left: position.x,
        top: position.y,
        cursor: dragging ? "grabbing" : "grab",
        userSelect: "none",
        zIndex: 9999,
      }}
    >
      <div className="thread-chat-container">
        <div className="header-wrapper">
          <div className="header">Comment</div>
          <div className="header-options">
            <div
              className="options-button"
              style={{ cursor: "pointer" }}
              onClick={(e) => {
                e.preventDefault();
                setOpenThreadOptions((prev) => !prev);
              }}
            >
              <KebabIcon />
            </div>
            {openThreadOptions && (
              <div className="options-list">
                <div className="options">Mark as Unread</div>
                <div className="options">Mark as Resolved</div>
                <div className="options delete" onClick={handleDeleteThread}>Delete Thread</div>
              </div>
            )}
            <button className="close-button" onClick={() => {
              setSelectedComment(null)
              setCommentPositionState(null)
            }}>
              <CloseIcon />
            </button>
          </div>
        </div>

        <div className="messages-wrapper" ref={messagesRef}>
          {selectedComment &&
            <Messages val={selectedComment} i={1} key={selectedComment.creatorId} isEditableThread={true} setEditedThread={setEditedThread} editedThread={editedThread} />
          }
          {messages && messages.map((val, i) => (
            <Messages val={val as any} i={i} key={val.replyId} setMessages={setMessages} setIsEditable={setIsEditable} isEditable={isEditable} isEditableThread={false} setMode={setMode} mode={mode} />
          ))}
        </div>

        <div className="send-message-wrapper">
          <div className={`input-container ${inputActive ? "active" : ""}`}>
            <textarea
              placeholder={commentPositionState && selectedComment === null ? "Type Thread Title" : "type something"}
              ref={textareaRef}
              value={value}
              onChange={(e) => setValue(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  e.preventDefault();
                  if (commentPositionState && selectedComment === null) {
                    handleCreateThread(e);
                  } else {
                    setMode("create");
                    handleCreateComments(e);
                    textareaRef.current?.blur();
                  }
                  setValue('')
                }
                if (e.key === "Escape") {
                  textareaRef.current?.blur();
                }
              }}
              onClick={() => {
                if (!commentPositionState && selectedComment !== null) {
                  setMode("create");
                }
              }}
              autoFocus={selectedComment === null}
              onBlur={() => setInputActive(false)}
              onFocus={() => setInputActive(true)}
              style={{ resize: "none" }}
            />
            <div
              className={`sent-button ${value === "" ? "disable-send-btn" : ""}`}
              onClick={(e) => {
                if (commentPositionState && selectedComment === null) {
                  handleCreateThread(e);
                } else {
                  setMode("create");
                  handleCreateComments(e);
                }
                setValue('')
              }}
            >
              <ExpandIcon />
            </div>
          </div>
        </div>

      </div>
      <ThreadSocketResponsesDev setMessages={setMessages} modeRef={modeRef} messages={messages} />
    </div >
  );
};

export default ThreadChat;
