import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { WizardIcon } from "../ui/Icons";
import { cn } from "../../lib/utils";
import { formatDate } from "../utils";
import { useEditContext, useFieldsEditContext } from "../client/editContext";
import { Loader2, AlertCircle, RotateCcw, Trash2 } from "lucide-react";
import { Checkbox } from "../../components/ui/checkbox";
import { useEffect, useState } from "react";
export function OperationItem({ operation: o, index: i, showUserName = false, showDescription = true, selected = false, onSelect, showCheckbox = false, hidePath = false, showLanguage = false, }) {
    const editContext = useEditContext();
    const fieldsContext = useFieldsEditContext();
    const [isDeleted, setIsDeleted] = useState(null);
    const isExecuting = o.executionStatus === "executing";
    const isFailed = o.executionStatus === "failed";
    const isCompleted = o.executionStatus === "completed";
    // Check if the item is deleted (lazily, only for operations that reference an item)
    useEffect(() => {
        if (!o.mainItem || isDeleted !== null) {
            return;
        }
        // Skip check for delete-items operations as they're about deletion, not deleted items
        if (o.type === "delete-items") {
            setIsDeleted(false);
            return;
        }
        // Check if item exists by trying to fetch it
        const checkItemExists = async () => {
            try {
                if (editContext?.itemsRepository && o.mainItem) {
                    const items = await editContext.itemsRepository.getItems([
                        o.mainItem,
                    ]);
                    setIsDeleted(items.length === 0 || items[0] === undefined);
                }
            }
            catch (error) {
                // If fetching fails, assume item is deleted
                setIsDeleted(true);
            }
        };
        // Debounce the check to avoid too many requests
        const timeoutId = setTimeout(checkItemExists, 100);
        return () => clearTimeout(timeoutId);
    }, [o.mainItem, o.type, editContext?.itemsRepository, isDeleted]);
    function getDate(o) {
        if (!o.date) {
            return "";
        }
        const date = new Date(o.date);
        if (isNaN(date.getTime())) {
            return "";
        }
        return formatDate(date);
    }
    function getOperationColor(type) {
        // Failed operations get red border
        if (isFailed)
            return "border-l-red-600";
        // Executing operations get a pulsing blue border
        if (isExecuting)
            return "border-l-blue-400";
        switch (type) {
            case "edit-field":
            case "update-rendering-parameters":
            case "update-rendering-rules":
                return "border-l-blue-500";
            case "create-item":
            case "add-component":
            case "add-version":
                return "border-l-green-500";
            case "move-component":
            case "move-items":
            case "rename-item":
                return "border-l-orange-500";
            case "delete-items":
            case "remove-component":
            case "remove-version":
                return "border-l-red-500";
            default:
                return "border-l-gray-400";
        }
    }
    function isOperationOnCurrentItem(o) {
        if (!editContext?.currentItemDescriptor || !o.mainItem) {
            return false;
        }
        const current = editContext.currentItemDescriptor;
        return (current.id === o.mainItem.id &&
            current.language === o.mainItem.language &&
            current.version === o.mainItem.version);
    }
    const isOnCurrentItem = isOperationOnCurrentItem(o);
    const colorClass = getOperationColor(o.type);
    function getSubpath(description, mainItemPath) {
        if (!mainItemPath || !description.startsWith(mainItemPath)) {
            return description;
        }
        const sub = description.substring(mainItemPath.length);
        if (sub === "" || sub === "/" || sub === "\\") {
            return "";
        }
        // Ensure it's a real sub-item (starts with path separator)
        if (sub.startsWith("/") || sub.startsWith("\\")) {
            return sub;
        }
        return description;
    }
    // Determine if item is deleted (true if explicitly checked and deleted, false otherwise)
    const itemIsDeleted = isDeleted === true;
    const className = cn("border-l-4 border-b border-gray-200 p-2 flex flex-col text-xs hover:bg-gray-100 font-light group", colorClass, {
        "text-gray-300 opacity-60": o.undone,
        "cursor-pointer": o.focus || (!isOnCurrentItem && o.mainItem && !itemIsDeleted),
        "bg-blue-50/50": isExecuting || selected,
        "bg-red-50/50": isFailed,
        "text-gray-500": itemIsDeleted && !o.undone,
        "opacity-75": itemIsDeleted && !o.undone,
    });
    const handleFocus = () => {
        if (o.focus) {
            const focusComponents = o.focus.split(":");
            if (focusComponents.length > 0) {
                editContext?.select([focusComponents[0]]);
            }
            if (focusComponents.length > 1 &&
                focusComponents[1] &&
                focusComponents[0]) {
                fieldsContext?.setFocusedField({
                    item: {
                        id: focusComponents[0],
                        language: editContext?.page?.item.language ||
                            editContext?.currentItemDescriptor?.language ||
                            "en",
                        version: editContext?.page?.item.version ||
                            editContext?.currentItemDescriptor?.version ||
                            0,
                    },
                    fieldId: focusComponents[1],
                }, false);
            }
        }
    };
    const handleClick = async (e) => {
        e.stopPropagation();
        // Don't navigate to deleted items
        if (itemIsDeleted) {
            return;
        }
        // If the operation is on a different item, navigate to it first
        if (!isOnCurrentItem && o.mainItem && editContext?.loadItem) {
            await editContext.loadItem(o.mainItem);
        }
        // Then handle focus if specified
        handleFocus();
    };
    return (_jsxs("div", { className: className, onClick: handleClick, "data-testid": "history-operation-item", "data-operation-id": o.id, "data-operation-title": o.title, "data-main-item-path": o.mainItemPath || "", children: [_jsxs("div", { className: "flex items-start gap-2", children: [showCheckbox && !o.undone && !isExecuting && (_jsx("div", { className: "mt-0.5", onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox, { checked: selected, onCheckedChange: (checked) => onSelect?.(!!checked), "aria-label": `Select ${o.title}`, "data-testid": "history-operation-checkbox" }) })), _jsx("div", { className: "min-w-0 flex-1", children: _jsxs("div", { className: "flex items-start justify-between", children: [_jsxs("div", { className: "flex min-w-0 flex-1 gap-1", children: [isExecuting && (_jsx(Loader2, { className: "h-4 w-4 shrink-0 animate-spin text-blue-500" })), isFailed && (_jsx(AlertCircle, { className: "h-4 w-4 shrink-0 text-red-500" })), !isExecuting && !isFailed && itemIsDeleted && (_jsx("span", { title: "Item has been deleted", children: _jsx(Trash2, { className: cn("h-4 w-4 shrink-0", o.undone ? "text-gray-200" : "text-gray-400") }) })), !isExecuting &&
                                            !isFailed &&
                                            !itemIsDeleted &&
                                            (o.user?.agentId || o.agentId) && (_jsx(WizardIcon, { className: cn("h-4 w-4 shrink-0", o.undone ? "text-gray-200" : "text-gray-500") })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "truncate", children: o.type === "edit-field" &&
                                                                o.fieldName
                                                                ? `Edit ${o.fieldName}`
                                                                : o.title }), o.mainItem?.version > 0 && (_jsxs("span", { className: "shrink-0 text-[10px] text-gray-400", children: ["v", o.mainItem.version] })), showLanguage && o.mainItem?.language && (_jsx("span", { className: "shrink-0 rounded bg-gray-100 px-1 py-0.5 text-[10px] text-gray-500", children: o.mainItem.language })), !o.undone && o.undoSupported === false && !isExecuting && (_jsx("span", { className: "shrink-0 rounded bg-gray-100 px-1 py-0.5 text-[10px] text-gray-600", title: o.undoNotSupportedReason || "Not undoable", children: "Not undoable" })), isExecuting && (_jsx("span", { className: "shrink-0 rounded bg-blue-100 px-1 py-0.5 text-[10px] text-blue-600", children: "Running" })), isFailed && (_jsx("span", { className: "shrink-0 rounded bg-red-100 px-1 py-0.5 text-[10px] text-red-600", children: "Failed" })), (o.user?.agentId || o.agentId) && (_jsx("button", { onClick: (e) => {
                                                                e.stopPropagation();
                                                                const agentId = o.user?.agentId || o.agentId;
                                                                // Open agents panel and load the agent (openAgent will load from history if needed)
                                                                if (editContext?.isMobile) {
                                                                    editContext.openSidebar("agents-panel");
                                                                }
                                                                else {
                                                                    editContext?.setShowAgentsPanel(true);
                                                                }
                                                                const dispatchOpenAgent = () => {
                                                                    window.dispatchEvent(new CustomEvent("editor:openAgent", {
                                                                        detail: { agentId },
                                                                    }));
                                                                };
                                                                if (editContext?.isMobile) {
                                                                    // 500ms delay on mobile to ensure the sidebar is mounted and listening.
                                                                    setTimeout(dispatchOpenAgent, 500);
                                                                }
                                                                else {
                                                                    dispatchOpenAgent();
                                                                }
                                                            }, className: "shrink-0 text-[10px] text-blue-600 hover:underline", title: "Open agent", children: "[Agent]" })), !o.undone && o.undoSupported === true && !isExecuting && (_jsx("button", { onClick: (e) => {
                                                                e.stopPropagation();
                                                                editContext?.operations.undoOperations([o.id]);
                                                            }, className: "ml-auto rounded p-0.5 text-gray-500 opacity-0 transition-opacity group-hover:opacity-100 hover:bg-gray-200 hover:text-gray-700", title: "Undo this operation", "data-testid": "history-operation-undo-button", children: _jsx(RotateCcw, { className: "h-3 w-3", strokeWidth: 2 }) }))] }), showDescription && o.description && (_jsx("div", { className: "mt-0.5 text-[10px] text-gray-500", children: getSubpath(o.description, o.mainItemPath) })), !hidePath && o.mainItemPath && (_jsx("div", { className: "mt-0.5 truncate text-[10px] text-gray-400", title: o.mainItemPath, children: o.mainItemPath }))] })] }), _jsxs("div", { className: "ml-2 min-w-0 text-right", children: [_jsx("div", { className: "text-xs leading-tight wrap-break-word", children: getDate(o) }), showUserName && !o.user?.agentId && !o.agentId && (_jsx("div", { className: "text-xs", children: o.user?.name }))] })] }) })] }), isExecuting && o.progress !== undefined && (_jsxs("div", { className: "mt-1.5 w-full", children: [_jsxs("div", { className: "relative h-1 w-full overflow-hidden rounded-full bg-gray-200", children: [_jsx("div", { className: "h-full bg-blue-500 transition-all duration-300", style: { width: `${Math.min(o.progress, 100)}%` } }), _jsx("div", { className: "absolute top-0 left-0 h-full animate-pulse bg-blue-400 opacity-50", style: {
                                    width: `${Math.max(Math.min(o.progress, 100), 2)}%`, // Minimum 2% width for visibility
                                    animationDuration: "1.5s",
                                } })] }), _jsxs("div", { className: "mt-0.5 flex justify-between text-[10px] text-gray-500", children: [_jsx("span", { className: "mr-2 flex-1 truncate", children: o.statusMessage || "Processing..." }), _jsxs("span", { className: "shrink-0", children: [o.progress, "%"] })] })] })), isExecuting && o.progress === undefined && o.statusMessage && (_jsx("div", { className: "mt-1 text-[10px] text-blue-600", children: o.statusMessage })), isFailed && o.errorMessage && (_jsx("div", { className: "mt-1 text-[10px] text-red-600", children: o.errorMessage }))] }));
}
//# sourceMappingURL=OperationItem.js.map