import { jsx as _jsx } from "react/jsx-runtime";
import { useEffect, useRef, useState } from "react";
import { useEditContext, useFieldsEditContext } from "../client/editContext";
import { createOrUpdateComment, deleteComment, resolveComment, unresolveComment, } from "../services/reviewsService";
// import { startAgent, StartAgentRequest } from "../services/agentService";
import { openAiAgentForComment } from "./commentAi";
import { useDebouncedCallback } from "use-debounce";
import { CommentView } from "./CommentView";
import { CommentEditor, COMMENT_INPUT_PLACEHOLDER } from "./CommentEditor";
import { toast } from "sonner";
import { LicenseFeatures, useFeature } from "../../licensing";
import { canReplyToComment, getCommentParentSnippet, } from "./feedbackCommentRules";
import { FeedbackCardFrame, getCommentContextSegments } from "./FeedbackCard";
import { cn } from "../../lib/utils";
import { selectFeedbackComment } from "./feedbackSelection";
import { activateCommentsMode } from "./openCommentsFeedback";
export function Comment({ comment, availableTags = [], rootCommentId, resolvedAuthorName, onReply, variant = "card", showContextHeader = true, showEditorCancelButton = true, }) {
    const editContext = useEditContext();
    const fieldsContext = useFieldsEditContext();
    const canUseAi = useFeature(LicenseFeatures.AI);
    const [isEditing, setIsEditing] = useState(false);
    const [isSaving, setIsSaving] = useState(false);
    const ref = useRef(null);
    useEffect(() => {
        if (comment.isNew)
            setIsEditing(true);
    }, [comment]);
    const isSelected = comment.id === editContext?.selectedComment?.id;
    useEffect(() => {
        if (isSelected && ref.current) {
            ref.current.scrollIntoView({ behavior: "smooth", block: "nearest" });
        }
    }, [isSelected]);
    const canDelete = !comment.isNew &&
        (comment.author === editContext?.user?.name ||
            editContext?.user?.isAdministrator === true);
    const canEdit = !comment.isNew &&
        !comment.isResolved &&
        comment.author === editContext?.user?.name;
    const isRootComment = !rootCommentId || comment.id === rootCommentId;
    const rootComment = rootCommentId
        ? editContext?.comments.find((c) => c.id === rootCommentId)
        : comment;
    const threadIsResolved = !!rootComment?.isResolved;
    const canResolve = isRootComment && !comment.isNew && !editContext?.readonly;
    const setCommentsDebounced = useDebouncedCallback(() => {
        if (!editContext?.setComments)
            return;
        editContext.setComments([...editContext.comments]);
    }, 300);
    const handleSave = async (text, tags) => {
        activateCommentsMode(editContext, { reason: "comment-save" });
        comment.text = text;
        comment.tags = tags.join(",");
        setIsSaving(true);
        try {
            const item = await editContext?.itemsRepository?.getItem({
                id: comment.itemId,
                language: comment.language,
                version: comment.version,
            });
            if (item && comment.fieldId) {
                comment.fieldValue = item.fields.find((f) => f.id === comment.fieldId)?.rawValue;
            }
            const result = await createOrUpdateComment(comment);
            if (result.type === "error" || result.type === "unauthorized") {
                console.error("Failed to save comment:", result);
                if (result.rawDetails) {
                    console.error("Full error details (including stack trace):\n", result.rawDetails);
                }
                toast.error(result.details || result.summary || "Failed to save comment");
                return;
            }
            if (editContext?.setComments) {
                editContext.setComments(editContext.comments.map((c) => c.id === comment.id ? { ...comment, isNew: false } : c));
            }
            setIsEditing(false);
        }
        catch (error) {
            console.error("Failed to save comment:", error);
            toast.error(error instanceof Error ? error.message : "Failed to save comment");
        }
        finally {
            setIsSaving(false);
        }
    };
    const handleCancel = () => {
        if (comment.isNew) {
            if (editContext?.setComments) {
                editContext.setComments([
                    ...editContext.comments.filter((c) => c.id !== comment.id),
                ]);
            }
        }
        else {
            setIsEditing(false);
        }
    };
    const handleDelete = async () => {
        try {
            const result = await deleteComment(comment);
            if (result.type === "error" || result.type === "unauthorized") {
                console.error("Failed to delete comment:", result);
                if (result.rawDetails) {
                    console.error("Full error details (including stack trace):\n", result.rawDetails);
                }
                toast.error(result.details || result.summary || "Failed to delete comment");
            }
            else {
                if (editContext?.setComments) {
                    editContext.setComments(editContext.comments.filter((c) => c.id !== comment.id));
                }
            }
        }
        catch (error) {
            console.error("Failed to delete comment:", error);
            toast.error(error instanceof Error ? error.message : "Failed to delete comment");
        }
    };
    const handleResolve = async () => {
        try {
            const result = await resolveComment(comment);
            if (result.type === "error" || result.type === "unauthorized") {
                console.error("Failed to resolve comment:", result);
                if (result.rawDetails) {
                    console.error("Full error details (including stack trace):\n", result.rawDetails);
                }
                toast.error(result.details || result.summary || "Failed to resolve comment");
            }
            else if (editContext?.setComments) {
                const resolvedComment = result.data;
                editContext.setComments(editContext.comments.map((c) => {
                    if (c.id !== comment.id)
                        return c;
                    return {
                        ...c,
                        isResolved: true,
                        resolvedBy: resolvedComment?.resolvedBy ||
                            c.resolvedBy ||
                            editContext.user?.name,
                        resolvedDate: resolvedComment?.resolvedDate ||
                            c.resolvedDate ||
                            new Date().toISOString(),
                    };
                }));
            }
        }
        catch (error) {
            console.error("Failed to resolve comment:", error);
            toast.error(error instanceof Error ? error.message : "Failed to resolve comment");
        }
    };
    const handleUnresolve = async () => {
        try {
            const result = await unresolveComment(comment);
            if (result.type === "error" || result.type === "unauthorized") {
                console.error("Failed to unresolve comment:", result);
                if (result.rawDetails) {
                    console.error("Full error details (including stack trace):\n", result.rawDetails);
                }
                toast.error(result.details || result.summary || "Failed to unresolve comment");
            }
            else if (editContext?.setComments) {
                editContext.setComments(editContext.comments.map((c) => {
                    if (c.id !== comment.id)
                        return c;
                    return {
                        ...c,
                        isResolved: false,
                        resolvedBy: undefined,
                        resolvedDate: undefined,
                    };
                }));
            }
        }
        catch (error) {
            console.error("Failed to unresolve comment:", error);
            toast.error(error instanceof Error ? error.message : "Failed to unresolve comment");
        }
    };
    const handleAiAction = async () => openAiAgentForComment(comment, editContext);
    const handleSelectComment = () => selectFeedbackComment(comment, editContext, fieldsContext);
    const parentSnippet = getCommentParentSnippet(comment, editContext?.comments);
    const canReply = canReplyToComment(comment, rootComment, editContext?.readonly);
    const cardContextSegments = showContextHeader && !comment.parentCommentId
        ? getCommentContextSegments(comment, editContext?.currentItemDescriptor?.name)
        : [];
    if (isEditing) {
        const editor = (_jsx(CommentEditor, { initialText: comment.text, onSave: handleSave, onCancel: handleCancel, isSaving: isSaving, availableTags: availableTags, selectedTags: comment.tags ? comment.tags.split(",").filter((t) => t.trim()) : [], placeholder: COMMENT_INPUT_PLACEHOLDER, submitLabel: comment.isNew ? "Comment" : "Save", showTagSelector: true, showCancelButton: showEditorCancelButton }));
        if (variant === "inline") {
            return (_jsx("div", { ref: ref, className: "mb-3", children: editor }));
        }
        return (_jsx(FeedbackCardFrame, { contextSegments: cardContextSegments, selected: isSelected, children: editor }));
    }
    const content = (_jsx("div", { className: cn("cursor-pointer", variant === "card" && "contents"), onClick: variant === "inline"
            ? async (event) => {
                event.stopPropagation();
                await handleSelectComment();
            }
            : undefined, children: _jsx(CommentView, { comment: comment, canEdit: canEdit, canDelete: canDelete, canResolve: canResolve, availableTags: availableTags, basePageName: editContext?.currentItemDescriptor?.name, basePageId: editContext?.currentItemDescriptor?.id, parentSnippet: parentSnippet, resolvedAuthorName: resolvedAuthorName, onEdit: () => setIsEditing(true), onDelete: handleDelete, onResolve: canResolve ? handleResolve : undefined, onUnresolve: canResolve ? handleUnresolve : undefined, onAiAction: canUseAi ? handleAiAction : undefined, onReply: canReply && onReply ? () => onReply(comment) : undefined, showCommentIcon: false, showContextInfo: variant === "card" && !showContextHeader, compact: variant === "inline" }) }, comment.id));
    if (variant === "inline") {
        return (_jsx("div", { ref: ref, "data-testid": "comment", className: "mb-4", children: content }));
    }
    return (_jsx("div", { ref: ref, children: _jsx(FeedbackCardFrame, { contextSegments: cardContextSegments, selected: isSelected, testId: "comment", className: "cursor-pointer", onClick: handleSelectComment, children: content }) }));
}
//# sourceMappingURL=Comment.js.map