import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { getInsertOptionsForCurrentSelection } from "../utils/insertOptions";
import { ArrowDownIcon } from "../ui/Icons";
import { getAbsoluteIconUrl, useCollapsedSections } from "../utils";
import { cn } from "../../lib/utils";
import { sanitizeSvg } from "../../lib/sanitize";
import { useEditContext } from "../client/editContext";
import { SearchInput, highlightMatch } from "../../components/SearchInput";
import { useCallback, useState, useRef, useEffect } from "react";
import { AlertTriangle } from "lucide-react";
import { useDragInsertionGesture } from "../page-editor-chrome/useDragInsertionGesture";
export function ComponentPalette() {
    const editContext = useEditContext();
    const [filter, setFilter] = useState("");
    const filterRef = useRef(null);
    const { isSectionCollapsed, toggleSection } = useCollapsedSections();
    const insertOptions = getInsertOptionsForCurrentSelection(editContext);
    // Auto-focus filter input when typing
    useEffect(() => {
        function handleKeyDown(event) {
            // Only handle if the filter input is not already focused
            if (document.activeElement === filterRef.current) {
                return;
            }
            // Don't steal focus if user is typing in an input field, textarea, or contenteditable element
            const activeElement = document.activeElement;
            if (activeElement &&
                (activeElement.tagName === "INPUT" ||
                    activeElement.tagName === "TEXTAREA" ||
                    activeElement.isContentEditable)) {
                return;
            }
            // Only handle printable characters (not special keys like arrows, escape, etc.)
            if (event.key.length === 1 &&
                !event.ctrlKey &&
                !event.metaKey &&
                !event.altKey) {
                // Focus the filter input
                filterRef.current?.focus();
                // Clear current filter and set to the typed character
                setFilter(event.key);
                // Prevent the default action to avoid any other handlers
                event.preventDefault();
            }
        }
        // Add event listener to the document
        document.addEventListener("keydown", handleKeyDown);
        // Cleanup
        return () => {
            document.removeEventListener("keydown", handleKeyDown);
        };
    }, []);
    const insertOptionsByGroup = insertOptions.reduce((acc, value) => {
        const group = value.group || "Other";
        if (!acc[group]) {
            acc[group] = [];
        }
        acc[group].push(value);
        return acc;
    }, {});
    return (_jsxs("div", { className: "tour-component-palette relative flex h-full flex-col", "data-testid": "component-palette", children: [_jsx("div", { className: "p-4", children: _jsx(SearchInput, { ref: filterRef, value: filter, onChange: setFilter, className: "border-border-default", placeholder: "Filter..." }) }), _jsx("div", { className: "relative flex-1", children: _jsx("div", { className: "absolute inset-0 overflow-y-auto", children: Object.keys(insertOptionsByGroup)
                        .sort()
                        .map((group, index) => {
                        const options = insertOptionsByGroup[group].filter((x) => !x.isHidden).filter((x) => x.name.toLowerCase().indexOf(filter.toLowerCase()) > -1);
                        if (options.length === 0)
                            return;
                        const isCollapsed = isSectionCollapsed(`palette.${group}`);
                        return (_jsxs("div", { className: cn("m-4", index > 0 ? "border-border-default border-t" : ""), children: [_jsxs("div", { className: "mt-2 mb-3 flex cursor-pointer items-center gap-2 text-xs font-medium select-none", onClick: () => toggleSection(`palette.${group}`), children: [_jsx(ArrowDownIcon, { className: cn("transition-transform", isCollapsed ? "-rotate-90" : "") }), " ", group] }), !isCollapsed && (_jsx("div", { className: "grid grid-cols-[repeat(auto-fill,_minmax(96px,_1fr))] gap-4", children: options.map((option) => {
                                        return (_jsx(PaletteOptionCard, { option: option, filter: filter }, option.typeId));
                                    }) }))] }, group));
                    }) }) })] }));
}
function PaletteOptionCard({ option, filter, }) {
    const editContext = useEditContext();
    const pageViewContext = editContext.getActiveSlotContext()?.primaryPageViewContext;
    const isDraggable = !option.isInvalid;
    const suppressNextClickRef = useRef(false);
    const hasThumbnail = !option.svg && !!option.thumbnail;
    const hasIcon = !option.svg && !!option.icon;
    const thumbnailUrl = hasThumbnail
        ? getAbsoluteIconUrl(option.thumbnail)
        : undefined;
    const { onPointerDown } = useDragInsertionGesture({
        iframe: pageViewContext?.editorIframe,
        pageViewContext,
        enabled: isDraggable,
        preventDefaultOnPointerDown: false,
        getStartDetail: useCallback(() => ({
            dragObject: {
                type: "template",
                typeId: option.typeId,
                name: option.name,
                ...(thumbnailUrl ? { thumbnailUrl } : {}),
            },
        }), [option.name, option.typeId, thumbnailUrl]),
        onStart: useCallback(() => {
            editContext.setSelectedForInsertion("");
        }, [editContext]),
        onEnd: useCallback(({ started, canceled }) => {
            if (!started) {
                if (!canceled) {
                    editContext.setSelectedForInsertion(option.typeId);
                }
                return;
            }
            suppressNextClickRef.current = true;
            window.setTimeout(() => {
                suppressNextClickRef.current = false;
            }, 0);
            editContext.setSelectedForInsertion("");
        }, [editContext, option.typeId]),
    });
    return (_jsxs("div", { id: "insert-component-" + option.typeId, onClick: (event) => {
            if (suppressNextClickRef.current) {
                suppressNextClickRef.current = false;
                event.preventDefault();
                event.stopPropagation();
                return;
            }
            editContext.setSelectedForInsertion(option.typeId);
        }, onPointerDown: (event) => {
            event.stopPropagation();
            if (event.button === 0) {
                editContext.setSelectedForInsertion(option.typeId);
            }
            onPointerDown(event);
        }, className: cn("border-border-default relative flex min-h-[88px] flex-col items-center gap-2 rounded border p-2 text-center text-xs break-words select-none", hasThumbnail ? "justify-start" : "justify-center", isDraggable ? "cursor-grab" : "", editContext.selectedForInsertion === option.typeId
            ? "border-feedback-blue"
            : ""), "data-testid": "insert-component-option", children: [option.svg && (_jsx("div", { className: "h-8 w-8", draggable: false, onDragStart: (e) => e.preventDefault(), dangerouslySetInnerHTML: {
                    __html: sanitizeSvg(option.svg),
                } })), hasThumbnail && (_jsx("div", { className: "border-border-default bg-neutral-grey-5 flex h-20 w-full items-center justify-center overflow-hidden rounded border", children: _jsx("img", { src: thumbnailUrl, alt: option.name, draggable: false, onDragStart: (e) => e.preventDefault(), className: "h-full w-full object-contain" }) })), !hasThumbnail && hasIcon && (_jsx("img", { src: getAbsoluteIconUrl(option.icon), alt: option.name, draggable: false, onDragStart: (e) => e.preventDefault(), className: "h-8 w-8 object-contain" })), _jsx("div", { className: "text-xs", children: highlightMatch(option.name, filter) }), option.isInvalid && (_jsx("span", { title: option.message, children: _jsx(AlertTriangle, { className: "text-feedback-red absolute top-0 right-0 h-4 w-4" }) }))] }));
}
//# sourceMappingURL=ComponentPalette.js.map