import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useEditContext } from "../client/editContext";
import { Tooltip, TooltipContent, TooltipTrigger, } from "../../components/ui/tooltip";
import { Button } from "../../components/ui/button";
import { useState, useEffect, useRef } from "react";
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
import { cn } from "../../lib/utils";
import { Check, FileText, FolderTree, RefreshCcw, Rocket } from "lucide-react";
import { SimpleTable } from "../ui/SimpleTable";
import { SimpleIconButton } from "../ui/SimpleIconButton";
import { FilterInput } from "../../components/FilterInput";
import { ItemList } from "../ui/ItemList";
import { ScrollingContentTree } from "../ScrollingContentTree";
import { getWorkboxDescendants, } from "../services/contentService";
import { executeSearch } from "../services/searchService";
import { useDebouncedCallback } from "use-debounce";
import { toast } from "sonner";
import { Spinner } from "../ui/Spinner";
import { getAbsoluteIconUrl, getItemDescriptor } from "../utils";
import { PublishItemDialog } from "../ui/PublishItemDialog";
function getWorkboxItemKey(item) {
    return [
        item.id?.toLowerCase(),
        item.language?.toLowerCase(),
        item.version ?? 0,
        item.database?.toLowerCase() ?? "",
    ].join("|");
}
export function Workbox() {
    const [validationOverlayItem, setValidationOverlayItem] = useState();
    const [isValidationOpen, setIsValidationOpen] = useState(false);
    const [mode, setMode] = useState("page");
    const [selectedRootItem, setSelectedRootItem] = useState();
    const [rootSelectorOpen, setRootSelectorOpen] = useState(false);
    const [descendantWorkboxItems, setDescendantWorkboxItems] = useState([]);
    const [loadingDescendants, setLoadingDescendants] = useState(false);
    const [openingPublishDialog, setOpeningPublishDialog] = useState(false);
    const [descendantsTotalCount, setDescendantsTotalCount] = useState(0);
    const [descendantsIsTruncated, setDescendantsIsTruncated] = useState(false);
    const [iconByItemKey, setIconByItemKey] = useState({});
    // Root selector search state
    const [query, setQuery] = useState("");
    const [searchResults, setSearchResults] = useState([]);
    const [loading, setLoading] = useState(false);
    const [hoveredItem, setHoveredItem] = useState();
    const inputRef = useRef(null);
    const editContext = useEditContext();
    const validationResult = editContext?.validationResult;
    const workboxItemsForIconLookup = mode === "page"
        ? (editContext?.workboxItems ?? [])
        : descendantWorkboxItems;
    useEffect(() => {
        if (!editContext?.itemsRepository || workboxItemsForIconLookup.length === 0)
            return;
        const descriptorsMissingIcons = workboxItemsForIconLookup
            .filter((item) => !item.icon && !iconByItemKey[getWorkboxItemKey(item.item)])
            .map((item) => item.item);
        if (descriptorsMissingIcons.length === 0)
            return;
        let cancelled = false;
        editContext.itemsRepository
            .getItemsStubs(descriptorsMissingIcons, editContext.currentItemDescriptor)
            .then((stubs) => {
            if (cancelled || stubs.length === 0)
                return;
            setIconByItemKey((current) => {
                const next = { ...current };
                stubs.forEach((stub, index) => {
                    const descriptor = descriptorsMissingIcons[index];
                    if (!stub.icon)
                        return;
                    next[getWorkboxItemKey(stub)] = stub.icon;
                    if (descriptor) {
                        next[getWorkboxItemKey(descriptor)] = stub.icon;
                    }
                });
                return next;
            });
        })
            .catch((error) => {
            console.error("Error loading workbox item icons:", error);
        });
        return () => {
            cancelled = true;
        };
    }, [
        editContext?.itemsRepository,
        editContext?.currentItemDescriptor,
        iconByItemKey,
        workboxItemsForIconLookup,
    ]);
    // Load descendants when root item changes and mode is "root"
    useEffect(() => {
        if (mode === "root" && selectedRootItem) {
            loadDescendants(selectedRootItem);
        }
    }, [mode, selectedRootItem]);
    const loadDescendants = async (rootItem) => {
        setLoadingDescendants(true);
        try {
            const itemDescriptor = getItemDescriptor(rootItem);
            const result = await getWorkboxDescendants(itemDescriptor);
            if (result.data) {
                // Sort: non-final state items first, then by workflow commands count
                const sorted = result.data.items.sort((a, b) => {
                    if (a.isPublished === b.isPublished)
                        return ((b.workflowCommands?.length || 0) -
                            (a.workflowCommands?.length || 0));
                    return !a.isPublished || !a.isPublishable ? -1 : 1;
                });
                setDescendantWorkboxItems(sorted);
                setDescendantsTotalCount(result.data.totalCount);
                setDescendantsIsTruncated(result.data.isTruncated);
            }
        }
        catch (error) {
            console.error("Error loading workbox descendants:", error);
            toast.error("Failed to load workbox items");
        }
        finally {
            setLoadingDescendants(false);
        }
    };
    // Search handler for root selector
    const handleSearch = useDebouncedCallback(async (searchPrompt) => {
        if (!editContext || !searchPrompt) {
            setSearchResults([]);
            setLoading(false);
            return;
        }
        setLoading(true);
        const currentQuery = searchPrompt;
        // Check if it's a GUID
        const guidPattern = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
        if (guidPattern.test(searchPrompt)) {
            const item = await editContext.itemsRepository.getItem({
                id: searchPrompt,
                language: "en",
                version: 0,
            });
            if (item) {
                if (query === currentQuery) {
                    const resultItem = {
                        id: item.id,
                        name: item.name,
                        language: item.language || "en",
                        icon: item.icon,
                        path: item.path || item.name,
                        idPath: item.idPath,
                    };
                    setSearchResults([resultItem]);
                }
            }
            else {
                if (query === currentQuery) {
                    setSearchResults([]);
                }
            }
            setLoading(false);
            return;
        }
        // Regular search
        const result = await executeSearch({
            index: "master",
            query: searchPrompt,
            editContext,
            maxResults: 5,
        });
        if (query === currentQuery) {
            if (result.type == "success") {
                setSearchResults(result.data);
            }
            else {
                toast.error(result.response.statusText || "Error searching");
                setSearchResults([]);
            }
        }
        setLoading(false);
    }, 600);
    useEffect(() => {
        if (query) {
            setLoading(true);
            handleSearch(query);
        }
        else {
            setSearchResults([]);
            setLoading(false);
        }
    }, [query]);
    useEffect(() => {
        if (inputRef.current && rootSelectorOpen) {
            inputRef.current.focus();
        }
    }, [rootSelectorOpen]);
    const loadRootItem = async (selectedItem) => {
        if (Array.isArray(selectedItem) && selectedItem[0]) {
            selectedItem = selectedItem[0];
        }
        if (!selectedItem)
            return;
        const itemDescriptor = selectedItem;
        const item = await editContext?.itemsRepository.getItem({
            id: itemDescriptor.id,
            language: itemDescriptor.language,
            version: itemDescriptor.version || 0,
        });
        if (item) {
            setSelectedRootItem(item);
            setRootSelectorOpen(false);
            setQuery("");
            setSearchResults([]);
        }
    };
    if (!editContext)
        return null;
    // Determine which items to display based on mode
    const displayItems = mode === "page" ? editContext.workboxItems : descendantWorkboxItems;
    const currentPublishItem = mode === "root" ? selectedRootItem : editContext.item;
    const currentPublishDescriptor = mode === "root"
        ? currentPublishItem
            ? getItemDescriptor(currentPublishItem)
            : undefined
        : editContext.currentItemDescriptor;
    const currentPublishWorkboxItem = displayItems.find((item) => item.item.id === currentPublishDescriptor?.id &&
        item.item.language === currentPublishDescriptor?.language &&
        item.item.version === currentPublishDescriptor?.version);
    const canPublishCurrentItem = !!currentPublishDescriptor &&
        !openingPublishDialog &&
        !editContext.readonly &&
        (mode !== "root" ||
            (!!currentPublishItem &&
                currentPublishItem.canWriteItem &&
                currentPublishItem.canWriteLanguage)) &&
        (currentPublishWorkboxItem
            ? currentPublishWorkboxItem.isPublishable
            : true);
    const publishButtonTooltip = !currentPublishDescriptor
        ? mode === "root"
            ? "Select a root item to publish."
            : "No current item is available to publish."
        : mode === "root"
            ? "Publish the selected root item and its descendants."
            : "Publish the current item.";
    const publishCurrentItem = async () => {
        if (!currentPublishDescriptor || !canPublishCurrentItem) {
            return;
        }
        setOpeningPublishDialog(true);
        try {
            const item = currentPublishItem ||
                (await editContext.itemsRepository.getItem(currentPublishDescriptor));
            if (!item) {
                toast.error("Failed to load item for publishing.");
                return;
            }
            const result = await editContext.openDialog(PublishItemDialog, { item });
            if (result && mode === "root" && selectedRootItem) {
                await loadDescendants(selectedRootItem);
            }
        }
        catch {
            toast.error("Failed to open publish dialog.");
        }
        finally {
            setOpeningPublishDialog(false);
        }
    };
    const nameBodyTemplate = (wbItem) => {
        const icon = wbItem.icon || iconByItemKey[getWorkboxItemKey(wbItem.item)];
        return (_jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [icon && (_jsx("img", { src: getAbsoluteIconUrl(icon), alt: "", className: "mt-0.5 h-4 w-4 shrink-0 object-contain" })), _jsxs("div", { className: "min-w-0", children: [_jsxs("div", { className: "break-all", children: [wbItem.name, " ", _jsxs("span", { className: "text-neutral-grey-50", children: ["(", wbItem.item.language, ", ", wbItem.item.version, ")"] })] }), wbItem.path && (_jsx("div", { className: "text-neutral-grey-50 mt-0.5 text-xs break-all", children: wbItem.path }))] })] }));
    };
    const stateBodyTemplate = (item) => {
        if (item.isPublishable) {
            const targets = Object.keys(item.publishStatus);
            return targets.map((x) => (_jsxs("div", { children: [targets.length > 1 && (_jsxs(_Fragment, { children: [_jsx("b", { children: x }), ":"] })), item.publishStatus[x]] }, x)));
        }
        else
            return item.workflowState;
    };
    const actionsBodyTemplate = (item) => {
        return (_jsx("div", { className: "flex flex-wrap gap-1", children: !item.isFinalState &&
                item.workflowCommands?.map((action) => {
                    return (_jsx(Button, { className: "p-1 text-xs", onClick: async () => {
                            await editContext.operations.executeWorkflowCommand(item.item, action.id);
                            if (mode === "root" && selectedRootItem) {
                                loadDescendants(selectedRootItem);
                            }
                        }, size: "sm", children: action.name }, action.id));
                }) }));
    };
    const validationTemplate = (item) => {
        const validator = validationResult?.find((x) => x.item.id === item.item.id &&
            x.item.language === item.item.language &&
            x.item.version === item.item.version);
        if (!validator || !validator.results.length)
            return null;
        const isOpen = isValidationOpen &&
            validationOverlayItem?.item.id === item.item.id &&
            validationOverlayItem?.item.language === item.item.language &&
            validationOverlayItem?.item.version === item.item.version;
        return (_jsxs(Popover, { open: isOpen, onOpenChange: (open) => {
                setIsValidationOpen(open);
                setValidationOverlayItem(open ? item : undefined);
            }, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { type: "button", className: cn("hover:bg-neutral-grey-5 inline-flex h-5 min-w-5 items-center justify-center rounded px-1 text-xs", getValidationErrorLevelClass(validator.results.reduce((prev, curr) => Math.max(prev, curr.result), 0))), children: validator.results.length }) }), _jsxs(PopoverContent, { side: "left", align: "start", sideOffset: 8, collisionPadding: 8, className: "w-80 max-w-[calc(100vw-2rem)] overflow-hidden p-0", children: [_jsxs("div", { className: "border-border-default bg-neutral-grey-5 border-b px-3 py-2", children: [_jsx("div", { className: "text-neutral-grey-100 text-xs font-semibold", children: "Validation issues" }), _jsxs("div", { className: "text-neutral-grey-50 text-[11px]", children: [validator.results.length, " ", validator.results.length === 1 ? "issue" : "issues", " found"] })] }), _jsx("div", { className: "divide-border-default max-h-[60vh] divide-y overflow-auto", children: validator.results.map((x) => (_jsxs("div", { className: "flex flex-col gap-1 px-3 py-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("div", { className: "text-neutral-grey-100 truncate text-xs font-medium", title: x.fieldName, children: x.fieldName }), _jsx("span", { className: "bg-neutral-grey-5 text-neutral-grey-50 shrink-0 rounded-sm px-1.5 py-0.5 text-[10px] font-medium", children: x.validator })] }), _jsx("div", { className: "text-neutral-grey-50 truncate text-[11px]", title: x.itemName, children: x.itemName }), _jsx("div", { className: cn("text-xs break-words", getValidationErrorLevelClass(x.result)), children: x.message })] }, x.fieldId + x.itemId))) })] })] }));
    };
    const getValidationErrorLevelClass = (level) => {
        switch (level) {
            case 0:
                return "text-feedback-green";
            case 1:
                return "text-feedback-blue";
            case 2:
                return "text-feedback-orange";
            case 3:
                return "text-component-shared";
            case 4:
            case 5:
                return "text-feedback-red";
        }
    };
    const columns = [
        { body: nameBodyTemplate, header: "Item" },
        { body: stateBodyTemplate, header: "State" },
        { body: actionsBodyTemplate, header: "Actions" },
        {
            body: validationTemplate,
            align: "center",
            header: _jsx(Check, { className: "h-4 w-4" }),
        },
    ];
    const hasResults = searchResults.length > 0;
    const isLoadingDisplayItems = mode === "page" ? editContext.isWorkboxLoading : loadingDescendants;
    const hasDisplayItems = displayItems.length > 0;
    const isPageEmpty = mode === "page" &&
        !editContext.isWorkboxLoading &&
        editContext.workboxItems.length === 0;
    const isRootEmpty = mode === "root" &&
        !!selectedRootItem &&
        !loadingDescendants &&
        descendantWorkboxItems.length === 0;
    return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "border-border-default flex items-center gap-2 border-b p-2", children: [_jsxs("div", { className: "flex gap-1", children: [_jsx(SimpleIconButton, { icon: _jsx(FileText, { className: "h-4 w-4", strokeWidth: 1 }), label: "Current Page", selected: mode === "page", onClick: () => setMode("page"), size: "small" }), _jsx(SimpleIconButton, { icon: _jsx(FolderTree, { className: "h-4 w-4", strokeWidth: 1 }), label: "Browse Descendants", selected: mode === "root", onClick: () => setMode("root"), size: "small" }), mode === "root" && selectedRootItem && (_jsx(SimpleIconButton, { icon: _jsx(RefreshCcw, { className: cn("h-4 w-4", loadingDescendants && "animate-spin"), strokeWidth: 1 }), label: "Refresh", onClick: () => loadDescendants(selectedRootItem), size: "small", "data-testid": "refresh-workbox-button" }))] }), mode === "root" && (_jsxs(Popover, { open: rootSelectorOpen, onOpenChange: setRootSelectorOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("div", { className: "border-border-default badge-pad hover:bg-neutral-grey-5 flex-1 cursor-pointer rounded border text-xs", "data-testid": "root-selector-button", children: selectedRootItem ? (_jsxs("div", { className: "truncate", children: [_jsx("span", { className: "font-medium", children: selectedRootItem.name }), _jsx("span", { className: "text-neutral-grey-50 ml-1", children: selectedRootItem.path })] })) : (_jsx("span", { className: "text-neutral-grey-50", children: "Select root item..." })) }) }), _jsx(PopoverContent, { className: "w-96 p-0", align: "start", children: _jsxs("div", { className: "flex h-[50vh] max-h-[400px] max-w-96 min-w-96 flex-col overflow-hidden", children: [_jsx("div", { className: "border-border-default border-b p-2", children: _jsx(FilterInput, { value: query, onChange: setQuery, ref: inputRef, placeholder: "Search content...", loading: loading, className: "w-full", spinnerStyle: { width: "18px", height: "18px" } }) }), _jsxs("div", { className: "flex flex-1 flex-col overflow-hidden", children: [hasResults && (_jsx("div", { className: "border-border-default max-h-[50%] shrink-0 overflow-auto border-b", children: _jsx("div", { className: "p-2", children: _jsx(ItemList, { items: searchResults, onItemHover: setHoveredItem, onItemClick: loadRootItem, maxItems: 20, className: "max-h-full overflow-auto" }) }) })), _jsx("div", { className: "relative min-h-0 flex-1", children: _jsx("div", { className: "absolute inset-0 overflow-auto", children: _jsx(ScrollingContentTree, { hideRootNodes: true, selectedItemId: hoveredItem?.id ?? selectedRootItem?.id, onSelectionChange: loadRootItem }) }) })] })] }) })] })), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("div", { className: "ml-auto", children: _jsx(Button, { size: "xs", variant: "outline", onClick: publishCurrentItem, disabled: !canPublishCurrentItem, "data-testid": "publish-workbox-button", children: openingPublishDialog ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "sm" }), " Opening..."] })) : (_jsxs(_Fragment, { children: [_jsx(Rocket, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }), "Publish"] })) }) }) }), _jsx(TooltipContent, { children: publishButtonTooltip })] })] }), _jsxs("div", { className: "flex-1 overflow-auto", children: [mode === "page" && editContext.isWorkboxLoading && (_jsxs("div", { className: "text-neutral-grey-50 flex h-full items-center justify-center gap-2 text-xs", children: [_jsx(Spinner, { size: "sm" }), " Loading..."] })), isPageEmpty && (_jsx("div", { className: "text-neutral-grey-50 flex h-full items-center justify-center text-xs", children: "No items to display" })), mode === "root" && !selectedRootItem && (_jsx("div", { className: "text-neutral-grey-50 flex h-full items-center justify-center text-xs", children: "Select a root item to view descendants" })), mode === "root" && selectedRootItem && loadingDescendants && (_jsxs("div", { className: "text-neutral-grey-50 flex h-full items-center justify-center gap-2 text-xs", children: [_jsx(Spinner, { size: "sm" }), " Loading..."] })), isRootEmpty && (_jsx("div", { className: "text-neutral-grey-50 flex h-full items-center justify-center text-xs", children: "No items pending workflow approval" })), !isLoadingDisplayItems && hasDisplayItems && (_jsxs(_Fragment, { children: [mode === "root" && descendantsIsTruncated && (_jsxs("div", { className: "border-component-shared bg-component-shared-drop-zone text-component-shared border-b px-3 py-2 text-xs", children: ["Showing ", descendantWorkboxItems.length, " of", " ", descendantsTotalCount, " items pending workflow approval"] })), _jsx(SimpleTable, { items: displayItems, columns: columns })] }))] })] }));
}
//# sourceMappingURL=Workbox.js.map