import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
import { useCallback, useEffect, useRef, useState, } from "react";
import { ChevronDown, ChevronLeft, ChevronRight, ChevronUp, ClipboardCheck, } from "lucide-react";
import { CountBadge } from "../../components/ui/badge";
import { DeleteIcon } from "../../components/ui/delete-icon";
import { Label } from "../../components/ui/label";
import { Switch } from "../../components/ui/switch";
import { useEditContext } from "../client/editContext";
import { getAbsoluteIconUrl } from "../utils";
import { TreeListSelector } from "./TreeListSelector";
import { Splitter } from "./Splitter";
import { SimpleIconButton } from "./SimpleIconButton";
export function ItemCollectionEditor({ items, selectedInTree, onSelectedInTreeChange, selectedFromList, onSelectedFromListChange, onAddToList, onRemoveFromList, onAddItem, onRemoveItem, onToggleSubitems, language, rootItemIds = [], selectedItemsLabel = "Selected Items", emptyMessage = "No items selected", emptyHint = "Browse or search to add items", height = 340, subitemCounts, expandIdPath, localStorageKey = "item-collection-editor-splitter", frameless = false, treeSearchContainerClassName, }) {
    const editContext = useEditContext();
    const isMobile = editContext?.isMobile ?? false;
    const editorRef = useRef(null);
    const [isDragOverList, setIsDragOverList] = useState(false);
    const [isCompactLayout, setIsCompactLayout] = useState(isMobile);
    useEffect(() => {
        const node = editorRef.current;
        if (!node || typeof window === "undefined") {
            setIsCompactLayout(isMobile);
            return;
        }
        const updateLayout = () => {
            setIsCompactLayout(isMobile || node.clientWidth < 560);
        };
        updateLayout();
        window.addEventListener("resize", updateLayout);
        if (typeof ResizeObserver === "undefined") {
            return () => window.removeEventListener("resize", updateLayout);
        }
        const observer = new ResizeObserver(updateLayout);
        observer.observe(node);
        return () => {
            observer.disconnect();
            window.removeEventListener("resize", updateLayout);
        };
    }, [isMobile]);
    const handleDropFromTree = useCallback((event) => {
        event.preventDefault();
        setIsDragOverList(false);
        const dragObject = editContext?.dragObject;
        if (dragObject?.type !== "items" || !dragObject.items?.length) {
            return;
        }
        const draggedItems = dragObject.items.map((item) => {
            const descriptor = item;
            return {
                id: descriptor.id,
                name: descriptor.name || descriptor.path || descriptor.id,
                displayName: descriptor.displayName,
                icon: descriptor.icon,
                path: descriptor.path,
                idPath: descriptor.idPath,
                language: descriptor.language,
                version: descriptor.version,
            };
        });
        void onAddToList(draggedItems);
    }, [editContext?.dragObject, onAddToList]);
    const handleDragOverList = useCallback((event) => {
        const dragObject = editContext?.dragObject;
        if (dragObject?.type !== "items") {
            return;
        }
        event.preventDefault();
        event.dataTransfer.dropEffect = "copy";
        setIsDragOverList(true);
    }, [editContext?.dragObject]);
    const handleDragLeaveList = useCallback((event) => {
        const relatedTarget = event.relatedTarget;
        const currentTarget = event.currentTarget;
        if (!currentTarget.contains(relatedTarget)) {
            setIsDragOverList(false);
        }
    }, []);
    useEffect(() => {
        const selectedItemIdSet = new Set(items.map((item) => item.descriptor.id));
        if (!selectedInTree.some((item) => selectedItemIdSet.has(item.id))) {
            return;
        }
        onSelectedInTreeChange(selectedInTree.filter((item) => !selectedItemIdSet.has(item.id)));
    }, [items, selectedInTree, onSelectedInTreeChange]);
    const selectedItemIds = items.map((item) => item.descriptor.id);
    const checkedTreeItemIds = [
        ...selectedItemIds,
        ...selectedInTree
            .map((item) => item.id)
            .filter((id) => !selectedItemIds.includes(id)),
    ];
    const handleTreeSelectionChange = useCallback((treeItems, checkedIds) => {
        const checkedIdSet = new Set(checkedIds ?? treeItems.map((item) => item.id));
        const selectedItemIdSet = new Set(items.map((item) => item.descriptor.id));
        const nextTreeSelection = treeItems.filter((item) => !selectedItemIdSet.has(item.id));
        const itemsToAdd = nextTreeSelection.filter((item) => checkedIdSet.has(item.id));
        const removedIndexes = items
            .map((item, index) => ({ id: item.descriptor.id, index }))
            .filter((item) => !checkedIdSet.has(item.id))
            .map((item) => item.index)
            .sort((a, b) => b - a);
        onSelectedInTreeChange(nextTreeSelection);
        if (itemsToAdd.length > 0) {
            void onAddToList(itemsToAdd);
        }
        if (removedIndexes.length > 0) {
            onSelectedFromListChange(selectedFromList.filter((item) => checkedIdSet.has(item.descriptor.id)));
            for (const index of removedIndexes) {
                onRemoveItem(index);
            }
        }
    }, [
        items,
        onAddToList,
        onRemoveItem,
        onSelectedFromListChange,
        onSelectedInTreeChange,
        selectedFromList,
    ]);
    const editorHeight = typeof height === "number" ? `${height}px` : height;
    const renderSelectionTotal = () => {
        if (items.length === 0)
            return null;
        let total = 0;
        let pending = false;
        for (const item of items) {
            total += 1;
            if (item.includeSubitems && subitemCounts) {
                const countState = subitemCounts[item.descriptor.id];
                if (countState === undefined || countState === "loading") {
                    pending = true;
                }
                else if (countState !== "error") {
                    total += countState.count;
                    if (!countState.complete)
                        pending = true;
                }
            }
        }
        return (_jsxs(CountBadge, { title: pending
                ? "Counting subitems..."
                : `${total} item${total === 1 ? "" : "s"} will be translated`, children: [total, pending && "+"] }));
    };
    const renderSubitemCount = (item) => {
        if (!item.includeSubitems || !subitemCounts)
            return null;
        const countState = subitemCounts[item.descriptor.id];
        if (countState === undefined)
            return null;
        const isObject = countState !== "loading" && countState !== "error";
        const count = isObject ? countState.count : null;
        const streaming = isObject && !countState.complete;
        const text = countState === "loading"
            ? "..."
            : countState === "error"
                ? "?"
                : `+${count}${streaming ? "+" : ""}`;
        return (_jsx(CountBadge, { title: count !== null
                ? `${count}${streaming ? "+" : ""} subitem${count === 1 ? "" : "s"} will be included${streaming ? " (still counting)" : ""}`
                : countState === "loading"
                    ? "Counting subitems..."
                    : "Failed to count subitems", children: text }));
    };
    const getItemIcon = (item) => item.descriptor.icon;
    const treePanel = (_jsx(TreeListSelector, { language: language, rootItemIds: rootItemIds, selectedItemIds: checkedTreeItemIds, onSelectionChange: handleTreeSelectionChange, onDoubleClick: onAddItem, onItemSelected: onAddItem, expandIdPath: expandIdPath, enableDragAndDrop: true, enableItemDrop: false, isDraggable: () => true, showGrabCursorForDraggableNodes: false, nodeCursor: "default", showCheckboxes: true, searchContainerClassName: treeSearchContainerClassName }));
    const selectedItemsPanel = (_jsx("div", { className: "relative h-full w-full", onDrop: handleDropFromTree, onDragOver: handleDragOverList, onDragLeave: handleDragLeaveList, children: _jsxs("div", { className: `bg-neutral-grey-5/30 flex h-full min-h-0 flex-col overflow-hidden transition-colors ${isDragOverList
                ? "bg-feedback-blue-light ring-feedback-blue ring-2 ring-inset"
                : ""}`, children: [_jsxs("div", { className: `flex shrink-0 items-center gap-2 ${frameless ? "mt-6 ml-6" : "px-3"}`, children: [_jsx("span", { className: "text-neutral-grey-50 text-xs font-medium tracking-wider", children: selectedItemsLabel }), renderSelectionTotal()] }), items.length > 0 ? (_jsx("div", { className: `min-h-0 flex-1 space-y-1.5 overflow-y-auto ${frameless ? "py-2 pr-2 pl-6" : "p-2"}`, children: items.map((item, index) => (_jsx("div", { className: `group flex cursor-pointer flex-col gap-1 rounded-lg border p-2 transition-all ${selectedFromList.includes(item)
                            ? "border-neutral-grey-15 bg-neutral-grey-5 ring-neutral-grey-10 ring-1"
                            : "border-border-default hover:border-neutral-grey-15 hover:bg-neutral-grey-5/50 bg-white"}`, onClick: (event) => {
                            if (event.ctrlKey || event.metaKey) {
                                if (selectedFromList.includes(item)) {
                                    onSelectedFromListChange(selectedFromList.filter((i) => i !== item));
                                }
                                else {
                                    onSelectedFromListChange([...selectedFromList, item]);
                                }
                            }
                            else if (selectedFromList.length === 1 &&
                                selectedFromList.includes(item)) {
                                onSelectedFromListChange([]);
                            }
                            else {
                                onSelectedFromListChange([item]);
                            }
                        }, onDoubleClick: () => {
                            onRemoveItem(index);
                            onSelectedFromListChange([]);
                        }, children: _jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [getItemIcon(item) && (_jsx("img", { src: getAbsoluteIconUrl(getItemIcon(item)), alt: "", className: "h-6 w-6 shrink-0 object-contain" })), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "text-neutral-grey-100 truncate text-[13px] font-medium", children: item.descriptor.displayName ||
                                                        item.descriptor.name ||
                                                        item.descriptor.path ||
                                                        item.descriptor.id }), item.descriptor.path && (_jsx("span", { className: "text-muted-foreground truncate text-[10px]", title: item.descriptor.path, children: item.descriptor.path }))] })] }), _jsxs("div", { className: "flex shrink-0 items-center gap-1", children: [_jsx(Label, { htmlFor: `subpages-${item.descriptor.id}-${index}`, className: "text-neutral-grey-50 cursor-pointer text-[10px] font-medium whitespace-nowrap", onClick: (event) => event.stopPropagation(), children: "Subitems" }), renderSubitemCount(item), _jsx(Switch, { id: `subpages-${item.descriptor.id}-${index}`, checked: item.includeSubitems, onCheckedChange: () => onToggleSubitems(index), onClick: (event) => event.stopPropagation(), className: "scale-[0.6]" }), _jsx(SimpleIconButton, { label: "Remove item", icon: _jsx(DeleteIcon, { size: "md" }), showTooltip: false, title: "Remove item", className: "text-neutral-grey-50 hover:bg-neutral-grey-5 hover:text-neutral-grey-100 h-6 w-6 shrink-0 p-0 opacity-0 transition-all group-hover:opacity-100", onClick: (event) => {
                                                event.stopPropagation();
                                                onRemoveItem(index);
                                            } })] })] }) }, `${item.descriptor.id}-${index}`))) })) : (_jsxs("div", { className: "flex min-h-0 flex-1 flex-col items-center justify-center gap-3 p-8 text-center", children: [_jsx("div", { className: "bg-neutral-grey-5/50 ring-border-default rounded-full p-4 ring-8", children: _jsx(ClipboardCheck, { className: "text-neutral-grey-50 h-6 w-6", strokeWidth: 1 }) }), _jsxs("div", { className: "space-y-1", children: [_jsx("p", { className: "text-neutral-grey-50 text-sm font-medium", children: isDragOverList ? "Drop items here" : emptyMessage }), _jsx("p", { className: "text-muted-foreground text-xs", children: isDragOverList
                                        ? "Release to add them to the selected items list"
                                        : emptyHint })] })] }))] }) }));
    if (isCompactLayout) {
        return (_jsx("div", { ref: editorRef, "data-testid": "item-collection-editor", className: frameless
                ? "flex h-full w-full overflow-hidden bg-white"
                : "border-border-default flex h-full w-full overflow-hidden rounded-xl border bg-white", style: { height: editorHeight }, children: _jsxs("div", { className: "flex h-full min-h-0 w-full flex-col", children: [_jsx("div", { className: "border-border-default min-h-0 border-b", style: { flex: "1.35 1 0" }, children: treePanel }), _jsxs("div", { className: "border-border-default bg-neutral-grey-5 flex shrink-0 items-center justify-center gap-2 border-b px-2 py-1.5", children: [_jsx(SimpleIconButton, { label: "Add selected items", icon: _jsx(ChevronDown, { size: 14, strokeWidth: 1 }), onClick: () => void onAddToList(selectedInTree), disabled: selectedInTree.length === 0, showTooltip: false, className: "px-0" }), _jsx(SimpleIconButton, { label: "Remove selected items", icon: _jsx(ChevronUp, { size: 14, strokeWidth: 1 }), onClick: onRemoveFromList, disabled: selectedFromList.length === 0, showTooltip: false, className: "px-0" })] }), _jsx("div", { className: "min-h-[132px]", style: { flex: "0.85 1 0" }, children: selectedItemsPanel })] }) }));
    }
    return (_jsx("div", { ref: editorRef, "data-testid": "item-collection-editor", className: frameless
            ? "h-full w-full overflow-hidden bg-white"
            : "border-border-default h-full w-full overflow-hidden rounded-xl border bg-white", style: { height: editorHeight }, children: _jsx(Splitter, { className: "h-full w-full", direction: "horizontal", localStorageKey: localStorageKey, panels: [
                {
                    name: "treeSelector",
                    defaultSize: 50,
                    className: frameless ? "p-6" : undefined,
                    content: treePanel,
                },
                {
                    name: "selectedItems",
                    defaultSize: 50,
                    content: selectedItemsPanel,
                },
            ], handleContent: (index) => index === 0 ? (_jsxs("div", { className: "bg-neutral-grey-5 flex h-full w-full flex-col items-center justify-center gap-1 py-1", children: [_jsx(SimpleIconButton, { label: "Add", icon: _jsx(ChevronRight, { size: 14, strokeWidth: 1 }), onClick: () => void onAddToList(selectedInTree), disabled: selectedInTree.length === 0, showTooltip: false, className: "px-0" }), _jsx(SimpleIconButton, { label: "Remove", icon: _jsx(ChevronLeft, { size: 14, strokeWidth: 1 }), onClick: onRemoveFromList, disabled: selectedFromList.length === 0, showTooltip: false, className: "px-0" })] })) : null }) }));
}
//# sourceMappingURL=ItemCollectionEditor.js.map