import { jsxs, jsx } from 'react/jsx-runtime';
import { useState, useRef, useEffect, useCallback } from 'react';
import Icon from '../Icon/Icon.js';
import { ffid } from '../../utils/ffID/ffid.js';
import ChildComment from './childComment/ChildComment.js';
import useNode from './childComment/useNode.js';
import MentionUser from './mentionUser/MentionUser.js';
import { formatUserDetails } from './commentCommonUtils.js';
import { CHECK_AT_FOLLOWED_BY_WORD, DETECT_MENTIONED_USERNAME_AFTER_SPACE, DETECT_AT_CHAR_AT_START } from '../../validations/regex.js';
import Typography from '../Typography/Typography.js';
import Tooltip from '../Tooltip/Tooltip.js';

const Comments = ({ commentsData, handleAddComment, handleEditComment, handleDeleteComment, onCommentsDataChange, currentUser, isDisable = false, userDetails, createdByID, rowBreakCharCount = 83, isVewMode = false, deleteEnable = true, showTextarea = false, autoFocus = false, }) => {
    const [input, setInput] = useState('');
    const [commentData, setCommentsData] = useState([]);
    const [hasAtSymbol, setHasAtSymbol] = useState(false);
    const [usersObj, setUsersObj] = useState([]);
    const [mentionPosition, setMentionPosition] = useState({ top: 0, left: 0 });
    const [textAfterAt, setTextAfterAt] = useState('');
    const textareaRef = useRef(null);
    const selectSectionRef = useRef(null);
    const [enterKeyPressed, setEnterKeyPressed] = useState(false);
    useEffect(() => {
        const formattedUsersDetails = formatUserDetails(userDetails);
        setUsersObj(formattedUsersDetails);
    }, [userDetails]);
    const findNode = (nodes, id) => {
        for (const node of nodes) {
            if (node.id === id)
                return node;
            const found = findNode(node.comments, id);
            if (found)
                return found;
        }
        return null;
    };
    useEffect(() => {
        if (commentsData) {
            setCommentsData(commentsData);
        }
    }, [commentsData]);
    useEffect(() => {
        const handleClickOutside = (event) => {
            if (selectSectionRef.current &&
                !selectSectionRef.current.contains(event.target)) {
                setHasAtSymbol(false);
                setInput((existingTexts) => {
                    const splittedWords = existingTexts.split(' ');
                    if (splittedWords.length > 0 &&
                        splittedWords?.[splittedWords?.length - 1]?.startsWith('@')) {
                        return splittedWords.slice(0, -1).join(' ');
                    }
                    return existingTexts;
                });
            }
        };
        document.addEventListener('mousedown', handleClickOutside);
        return () => {
            document.removeEventListener('mousedown', handleClickOutside);
        };
    }, []);
    const { insertNode, editNode, deleteNode } = useNode();
    const handleInsertNode = (parentId, text, emailIds) => {
        if (!text.trim())
            return;
        const newComment = {
            id: ffid(),
            description: text,
            commentParentId: parentId,
            emailId: emailIds,
            comments: [],
            createdBy: currentUser?.createdBy,
            modifiedBy: currentUser?.modifiedBy,
            createdByUname: currentUser?.createdByUname,
            modifiedByUname: currentUser?.modifiedByUname,
            createdOn: new Date().toISOString(),
            modifiedOn: new Date().toISOString(),
        };
        setCommentsData((prevComments) => insertNode(prevComments, parentId, newComment));
        if (handleAddComment)
            handleAddComment(newComment, findNode(commentData, parentId));
    };
    const handleEditNode = useCallback((commentId, value, mentionedUsersEmail) => {
        const updatedTree = editNode(commentData, commentId, value);
        setCommentsData(updatedTree);
        const updatedNode = findNode(updatedTree, commentId);
        if (handleEditComment)
            handleEditComment(commentId, value, updatedNode, mentionedUsersEmail);
    }, [commentData, editNode, handleEditComment]);
    const handleDeleteNode = useCallback(async (commentId) => {
        try {
            if (handleDeleteComment) {
                const response = await handleDeleteComment(commentId);
                if (response?.success) {
                    const updatedTree = deleteNode(commentData, commentId);
                    setCommentsData(updatedTree);
                }
            }
        }
        catch (error) {
            console.error('Error deleting comment:', error);
        }
    }, [deleteNode, handleDeleteComment]);
    useEffect(() => {
        if (onCommentsDataChange) {
            onCommentsDataChange(commentData);
        }
    }, [commentData, onCommentsDataChange]);
    const handleAddNewComment = () => {
        if (!input.trim())
            return;
        const mentionedUserEmails = usersObj
            .filter((user) => {
            const regex = new RegExp(`@${user.name}\\b`, 'i');
            return regex.test(input);
        })
            .map((user) => user.emailId);
        const newComment = {
            id: ffid(),
            description: input,
            comments: [],
            createdBy: currentUser?.createdBy,
            modifiedBy: currentUser?.modifiedBy,
            createdByUname: currentUser?.createdByUname,
            modifiedByUname: currentUser?.modifiedByUname,
            createdOn: new Date().toISOString(),
            modifiedOn: new Date().toISOString(),
            commentParentId: '',
            emailId: mentionedUserEmails,
        };
        if (handleAddComment)
            handleAddComment(newComment, null);
        setCommentsData((prev) => [...prev, newComment]);
        setInput('');
    };
    const getCaretCoordinates = (element, position) => {
        const div = document.createElement('div');
        const copyStyle = getComputedStyle(element);
        div.style.cssText = `
      position: absolute;
      visibility: hidden;
      white-space: pre-wrap;
      word-wrap: break-word;
      overflow: auto;
      width: ${element.offsetWidth}px;
      height: ${element.offsetHeight}px;
      font-family: ${copyStyle.fontFamily};
      font-size: ${copyStyle.fontSize};
      padding: ${copyStyle.padding};
      border: ${copyStyle.border};
      box-sizing: ${copyStyle.boxSizing};
      line-height: ${copyStyle.lineHeight};
    `;
        div.scrollTop = element.scrollTop;
        div.scrollLeft = element.scrollLeft;
        document.body.appendChild(div);
        const text = element.value.slice(0, position);
        div.textContent = text || '.';
        const span = document.createElement('span');
        span.textContent = '.';
        div.appendChild(span);
        const spanRect = span.getBoundingClientRect();
        document.body.removeChild(div);
        return {
            top: spanRect.top,
            left: spanRect.left,
        };
    };
    useEffect(() => {
        const updateMentionPosition = () => {
            if (!textareaRef.current)
                return;
            const textareaEl = textareaRef?.current;
            const dropdownEl = selectSectionRef?.current;
            const caretPosition = textareaRef.current.selectionStart;
            const caretCoords = getCaretCoordinates(textareaEl, caretPosition);
            const dropdownHeight = dropdownEl?.getBoundingClientRect().height ?? 0;
            const inputRect = textareaEl?.getBoundingClientRect();
            if (!inputRect)
                return;
            const spaceBelow = window.innerHeight - inputRect.bottom;
            const spaceAbove = inputRect.top;
            const showAbove = spaceBelow < dropdownHeight && spaceAbove > dropdownHeight;
            setMentionPosition({
                top: showAbove
                    ? caretPosition - dropdownHeight - 16
                    : caretPosition + 32,
                left: caretCoords.left + 10,
            });
        };
        updateMentionPosition();
    }, [input]);
    const textAreaInputChange = (e) => {
        const textAreaValue = e.target.value;
        setInput(textAreaValue);
        const caretPosition = e.target.selectionStart;
        const textBeforeCaret = textAreaValue.slice(0, caretPosition);
        const match = textBeforeCaret.match(CHECK_AT_FOLLOWED_BY_WORD);
        const mentionWords = match?.[1] || '';
        setTextAfterAt(mentionWords);
        const hasExplicitAtSymbol = DETECT_AT_CHAR_AT_START.test(textBeforeCaret);
        setHasAtSymbol(!!hasExplicitAtSymbol);
        if (!textAreaValue) {
            setEnterKeyPressed(false);
        }
    };
    useEffect(() => {
        if (!input.includes('\n')) {
            setEnterKeyPressed(false);
        }
    }, [input]);
    const optionClicked = (name) => {
        if (!textareaRef.current)
            return;
        const caretPosition = textareaRef.current.selectionStart;
        const textBeforeCaret = input.slice(0, caretPosition);
        const mentionNameMatch = textBeforeCaret.match(DETECT_MENTIONED_USERNAME_AFTER_SPACE);
        if (mentionNameMatch) {
            const mentionNameStart = textBeforeCaret.lastIndexOf(mentionNameMatch[1] ?? '');
            const remainingText = input.slice(caretPosition);
            const mentionedUserName = `@${name} `;
            const newText = input.slice(0, mentionNameStart) + mentionedUserName + remainingText;
            setInput(newText);
            setHasAtSymbol(false);
            setTimeout(() => {
                textareaRef.current?.focus();
                const newCaretPos = mentionNameStart + mentionedUserName.length + 1;
                textareaRef.current?.setSelectionRange(newCaretPos, newCaretPos);
            }, 0);
        }
    };
    const handleKeyDown = (e) => {
        if (e.key === '@') {
            setHasAtSymbol(true);
        }
        else if (e.key === 'Backspace' && textareaRef.current) {
            const caretPos = textareaRef.current.selectionStart;
            const textBeforeCaret = input.slice(0, caretPos);
            if (textBeforeCaret.endsWith('@')) {
                setHasAtSymbol(false);
            }
            if (hasAtSymbol) {
                e.preventDefault();
                const before = input.slice(0, caretPos - 1);
                const after = input.slice(caretPos);
                const updated = before + after;
                setInput(updated);
                const newCaretPos = caretPos - 1;
                const newTextBeforeCaret = updated.slice(0, newCaretPos);
                const match = newTextBeforeCaret.match(CHECK_AT_FOLLOWED_BY_WORD);
                const mentionWord = match?.[1] || '';
                setTextAfterAt(mentionWord);
                setHasAtSymbol(!!match);
                setTimeout(() => {
                    textareaRef.current?.setSelectionRange(newCaretPos, newCaretPos);
                }, 0);
            }
        }
        if (e.key === 'Enter') {
            setEnterKeyPressed(true);
        }
    };
    return (jsxs("div", { className: "ff-comments-container-box", children: [!isVewMode && (jsxs("div", { className: `ff-first-comment ${showTextarea ? 'no-border' : ''}`, children: [jsx(Typography, { fontWeight: "semi-bold", className: "ff-comment-heading", children: "Comments" }), !showTextarea && (jsxs("div", { className: "input-wrapper", children: [jsx("textarea", { className: "inputContainer_input first_input", rows: enterKeyPressed ? 3 : input.length < rowBreakCharCount ? 1 : 3, autoFocus: autoFocus, value: input, onChange: (e) => textAreaInputChange(e), placeholder: "Add a comment", disabled: isDisable, ref: textareaRef, onKeyDown: handleKeyDown }), hasAtSymbol && (jsx("div", { id: "mention-user", style: {
                                    position: 'absolute',
                                    top: `${mentionPosition.top}px`,
                                    left: `${mentionPosition.left}px`,
                                }, children: jsx(MentionUser, { hasAtSymbol: hasAtSymbol, usersObj: usersObj, optionClicked: optionClicked, charsAfterAt: textAfterAt, mentionUserRef: selectSectionRef }) })), jsx("span", { className: "reply-comment", children: jsx(Tooltip, { title: "Add", children: jsx(Icon, { name: "comment_reply", onClick: handleAddNewComment, hoverEffect: true, disabled: Boolean(!input.length) }) }) })] }))] })), commentData.length > 0 &&
                commentData.map((comment) => (jsx(ChildComment, { handleInsertNode: handleInsertNode, handleEditNode: handleEditNode, handleDeleteNode: handleDeleteNode, comment: comment, depth: 0, isDisable: isDisable, userDetails: userDetails, isEditDeleteActionAllowed: comment.createdBy === createdByID, createdByID: createdByID, isVewMode: isVewMode, deleteEnable: deleteEnable }, comment.id)))] }));
};

export { Comments as default };
//# sourceMappingURL=Comments.js.map
