import { jsxs as _jsxs, jsx as _jsx, 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 { getItemDescriptor } from "../utils";
import { PublishItemDialog } from "../ui/PublishItemDialog";
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);
    // 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;
    // 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 id = wbItem.item.id + wbItem.item.language + wbItem.item.version;
        return (_jsx("div", { className: "flex items-center gap-2", children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { className: "cursor-help break-all", style: { position: "relative" }, children: [wbItem.name, " ", _jsxs("span", { className: "text-gray-500", children: ["(", wbItem.item.language, ", ", wbItem.item.version, ")"] })] }) }), _jsx(TooltipContent, { 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;
        return (_jsx("div", { className: cn("cursor-pointer", getValidationErrorLevelClass(validator.results.reduce((prev, curr) => Math.max(prev, curr.result), 0))), onClick: () => {
                setValidationOverlayItem(item);
                setIsValidationOpen(true);
            }, children: validator.results.length }));
    };
    const overlayResult = validationResult?.find((x) => x.item.id === validationOverlayItem?.item.id &&
        x.item.language === validationOverlayItem?.item.language &&
        x.item.version === validationOverlayItem?.item.version);
    const getValidationErrorLevelClass = (level) => {
        switch (level) {
            case 0:
                return "text-green-600";
            case 1:
                return "text-blue-600";
            case 2:
                return "text-yellow-600";
            case 3:
                return "text-orange-600";
            case 4:
            case 5:
                return "text-red-600";
        }
    };
    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;
    return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "flex items-center gap-2 border-b border-gray-200 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: "flex-1 cursor-pointer rounded border border-gray-200 px-2 py-1 text-xs hover:bg-gray-50", "data-testid": "root-selector-button", children: selectedRootItem ? (_jsxs("div", { className: "truncate", children: [_jsx("span", { className: "font-medium", children: selectedRootItem.name }), _jsx("span", { className: "ml-1 text-gray-500", children: selectedRootItem.path })] })) : (_jsx("span", { className: "text-gray-400", 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-b border-gray-200 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: "max-h-[50%] shrink-0 overflow-auto border-b border-gray-200", 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.workboxItems && (_jsx("div", { className: "flex h-full items-center justify-center text-xs text-gray-500", children: "No items to display" })), mode === "root" && !selectedRootItem && (_jsx("div", { className: "flex h-full items-center justify-center text-xs text-gray-500", children: "Select a root item to view descendants" })), mode === "root" && selectedRootItem && loadingDescendants && (_jsxs("div", { className: "flex h-full items-center justify-center gap-2 text-xs text-gray-500", children: [_jsx(Spinner, { size: "sm" }), " Loading..."] })), mode === "root" && selectedRootItem && !loadingDescendants && descendantWorkboxItems.length === 0 && (_jsx("div", { className: "flex h-full items-center justify-center text-xs text-gray-500", children: "No items pending workflow approval" })), displayItems && displayItems.length > 0 && (_jsxs(_Fragment, { children: [mode === "root" && descendantsIsTruncated && (_jsxs("div", { className: "border-b border-orange-200 bg-orange-50 px-3 py-2 text-xs text-orange-700", children: ["Showing ", descendantWorkboxItems.length, " of ", descendantsTotalCount, " items pending workflow approval"] })), _jsx(SimpleTable, { items: displayItems, columns: columns })] }))] }), _jsxs(Popover, { open: isValidationOpen, onOpenChange: setIsValidationOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("div", { style: { display: "none" } }) }), _jsx(PopoverContent, { className: "w-auto p-0", children: _jsxs("table", { className: "m-3 border-separate border-spacing-1 text-xs", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "text-left", children: "Item" }), _jsx("th", { className: "text-left", children: "Field" }), _jsx("th", { className: "text-left", children: "Validator" }), _jsx("th", { className: "text-left", children: "Message" })] }) }), _jsx("tbody", { children: overlayResult &&
                                        overlayResult.results.map((x) => (_jsxs("tr", { children: [_jsx("td", { children: x.itemName }), _jsx("td", { children: x.fieldName }), _jsx("td", { children: x.validator }), _jsx("td", { className: cn("max-w-48 text-xs break-all", getValidationErrorLevelClass(x.result)), children: x.message })] }, x.fieldId + x.itemId))) })] }) })] })] }));
}
//# sourceMappingURL=Workbox.js.map