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 { FileText, FolderTree, RefreshCcw, Rocket } from "lucide-react";
import { WorkboxItemsTable } from "../ui/WorkboxItemsTable";
import { SimpleIconButton } from "../ui/SimpleIconButton";
import { SearchInput } from "../../components/SearchInput";
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 { getItemDescriptor } from "../utils";
import { PublishItemDialog } from "../ui/PublishItemDialog";
export function Workbox() {
    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);
    // 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();
    // Load descendants when root item changes and mode is "root"
    useEffect(() => {
        if (mode === "root" && selectedRootItem) {
            loadDescendants(selectedRootItem);
        }
    }, [mode, selectedRootItem]);
    // Refresh the descendants list when one of this user's publish jobs reaches
    // a terminal state. Page mode is refreshed centrally in
    // useSocketMessageHandler so it also works while this sidebar is unmounted.
    useEffect(() => {
        if (mode !== "root" || !selectedRootItem)
            return;
        const unsubscribe = editContext?.addSocketMessageListener?.((message) => {
            if ((message.type === "operation:completed" ||
                message.type === "operation:failed") &&
                message.payload?.type === "publish-item") {
                loadDescendants(selectedRootItem);
            }
        });
        return unsubscribe;
    }, [mode, selectedRootItem, editContext?.addSocketMessageListener]);
    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);
    // Only a non-final workflow state blocks publishing. Items with no workflow
    // report isPublishable = false from the server, so gate on an actual
    // workflow state instead of the conflated flag.
    const blockedByWorkflowState = !!currentPublishWorkboxItem?.workflowState &&
        !currentPublishWorkboxItem.isPublishable;
    const canPublishCurrentItem = !!currentPublishDescriptor &&
        !openingPublishDialog &&
        !editContext.readonly &&
        (mode !== "root" ||
            (!!currentPublishItem &&
                currentPublishItem.canWriteItem &&
                currentPublishItem.canWriteLanguage)) &&
        !blockedByWorkflowState;
    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;
            }
            // The descendants list refreshes when the publish job completes (socket
            // listener below) — refreshing on dialog close would show stale state
            await editContext.openDialog(PublishItemDialog, { item });
        }
        catch {
            toast.error("Failed to open publish dialog.");
        }
        finally {
            setOpeningPublishDialog(false);
        }
    };
    const hasResults = searchResults.length > 0;
    const isLoadingDisplayItems = mode === "page" ? editContext.isWorkboxLoading : loadingDescendants;
    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(SearchInput, { 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 })] })] }), _jsx("div", { className: "flex-1 overflow-auto", children: 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" })) : (_jsx(WorkboxItemsTable, { items: displayItems, isLoading: isLoadingDisplayItems, emptyMessage: mode === "page"
                        ? "No items to display"
                        : "No items pending workflow approval", headerNotice: 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"] })) : undefined, onAfterWorkflowCommand: mode === "root" && selectedRootItem
                        ? () => loadDescendants(selectedRootItem)
                        : undefined })) })] }));
}
//# sourceMappingURL=Workbox.js.map