import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React, { useState, useEffect, useCallback, useMemo, useRef, } from "react";
import { Book, BookOpen, Loader2, Edit, ArrowLeft, ArrowRight, ChevronDown, ChevronRight, LocateFixed, Rocket, FileEdit, X, } from "lucide-react";
import { loadManualToc, loadManualSection, invalidateManualSectionCache, } from "../../services/aiService";
import { executeSearch } from "../../services/searchService";
import { FilterInput } from "../../../components/FilterInput";
import { MarkdownDisplay, } from "../../../components/MarkdownDisplay";
import { Tooltip, TooltipTrigger, TooltipContent, } from "../../../components/ui/tooltip";
import { useEditContext } from "../../client/editContext";
import { cn } from "../../../lib/utils";
import { sanitizeSvg } from "../../../lib/sanitize";
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "../../../components/ui/dropdown-menu";
/** Render a sanitized SVG string at a specific pixel size. */
function SvgIcon({ svg, size, className, }) {
    const sanitizedSvg = sanitizeSvg(svg).trim();
    return (_jsx("span", { className: cn("inline-flex items-center justify-center [&>svg]:block [&>svg]:h-full [&>svg]:w-full", className), style: { width: size, height: size }, dangerouslySetInnerHTML: { __html: sanitizedSvg } }));
}
const HIGHLIGHT_DURATION_MS = 2000;
const manualMarkdownComponents = {
    h1: ({ children }) => (_jsx("h1", { className: "mt-4 mb-0 text-xl font-bold text-gray-900", children: children })),
    h2: ({ children }) => (_jsx("h2", { className: "mt-3 mb-0 text-lg font-semibold text-gray-800", children: children })),
    h3: ({ children }) => (_jsx("h3", { className: "mt-2 mb-0 text-base font-semibold text-gray-700", children: children })),
    h4: ({ children }) => (_jsx("h4", { className: "mt-2 mb-0 text-sm font-semibold text-gray-700", children: children })),
};
// Parse the uiSelectors field
// Formats:
// - @selector-name: Description | Not found message
// - @reviews-sidebar: Description (sidebar-only, opens the sidebar without highlighting)
export function parseUiSelectors(uiSelectors) {
    const map = new Map();
    if (!uiSelectors)
        return map;
    const lines = uiSelectors
        .split(/\r?\n/)
        .map((line) => line.trim())
        .filter(Boolean);
    for (const line of lines) {
        // Format: @selector-name: ...
        const match = line.match(/^@([\w\-]+):\s*(.+)$/);
        if (match) {
            const name = match[1];
            const rest = match[2];
            if (!name || !rest)
                continue;
            const segments = rest
                .split("|")
                .map((segment) => segment.trim())
                .filter(Boolean);
            const description = segments.shift() ?? "";
            let notFoundMessage;
            let beforeAction;
            let afterAction;
            let availabilitySelector;
            for (const segment of segments) {
                if (segment.startsWith("beforeAction=")) {
                    beforeAction = segment.substring("beforeAction=".length).trim();
                    continue;
                }
                if (segment.startsWith("afterAction=")) {
                    afterAction = segment.substring("afterAction=".length).trim();
                    continue;
                }
                if (segment.startsWith("availabilitySelector=")) {
                    availabilitySelector = segment
                        .substring("availabilitySelector=".length)
                        .trim();
                    continue;
                }
                if (!notFoundMessage) {
                    notFoundMessage = segment;
                }
            }
            // Check if this is a sidebar-only selector (e.g., @reviews-sidebar)
            // These end with -sidebar
            const isSidebarOnly = name.endsWith("-sidebar");
            // Strip the -sidebar suffix to get the actual sidebar ID
            const sidebarId = isSidebarOnly
                ? name.replace(/-sidebar$/, "")
                : undefined;
            const parsed = {
                name,
                selector: isSidebarOnly ? "" : `@${name}`, // Empty selector for sidebar-only
                availabilitySelector,
                description,
                notFoundMessage: notFoundMessage || undefined,
                location: isSidebarOnly ? sidebarId : undefined, // Use actual sidebar ID (without -sidebar suffix) for sidebar-only
                isSidebarOnly,
                beforeAction,
                afterAction,
            };
            // Primary key remains the selector name
            map.set(name, parsed);
        }
    }
    return map;
}
function parseSelectorToken(selectorToken) {
    if (!selectorToken.startsWith("@"))
        return { selector: selectorToken };
    const raw = selectorToken.slice(1);
    // Preserve iframe: selectors (handled specially by expandSelector/highlightElement)
    if (raw.startsWith("iframe:"))
        return { selector: selectorToken };
    // Check for sidebar-only syntax: @sidebar-id-sidebar (e.g., @reviews-sidebar)
    // This opens the sidebar without highlighting any element inside it
    if (raw.endsWith("-sidebar") && /^[\w\-]+$/.test(raw)) {
        // Strip the -sidebar suffix to get the actual sidebar ID
        const sidebarId = raw.replace(/-sidebar$/, "");
        return {
            selector: "", // No element to highlight
            location: sidebarId, // The actual sidebar ID (without -sidebar suffix)
            isSidebarOnly: true,
        };
    }
    // Regular selector syntax: @selector-name
    return { selector: selectorToken };
}
// Expand @selector syntax to CSS selectors
export function expandSelector(selectorShorthand) {
    const { selector: normalized } = parseSelectorToken(selectorShorthand);
    // Remove leading @
    const selector = normalized.replace(/^@/, "");
    // Check for prefix patterns
    if (selector.startsWith(".")) {
        // Class selector: @.classname → .classname
        return selector;
    }
    if (selector.startsWith("#")) {
        // ID selector: @#id → #id
        return selector;
    }
    if (selector.startsWith("[")) {
        // Attribute selector: @[attr=value] → [attr=value]
        return selector;
    }
    if (selector.startsWith("iframe:")) {
        // Iframe selector: @iframe:selector → iframe:selector (handled by GuidanceOverlay)
        return selector;
    }
    // Default: data-testid selector: @name → [data-testid="name"]
    return `[data-testid="${selector}"]`;
}
function getElementsForSelector(selector) {
    const cssSelector = expandSelector(selector);
    if (cssSelector.startsWith("iframe:")) {
        const iframeSelector = cssSelector.substring(7);
        const iframe = document.querySelector("iframe.page-iframe");
        if (!iframe?.contentDocument) {
            return [];
        }
        return Array.from(iframe.contentDocument.querySelectorAll(iframeSelector));
    }
    return Array.from(document.querySelectorAll(cssSelector));
}
function shouldSkipHighlightScroll(element) {
    const rect = element.getBoundingClientRect();
    const computedStyle = window.getComputedStyle(element);
    const viewportPadding = 24;
    const isFixedLike = computedStyle.position === "fixed" || computedStyle.position === "sticky";
    const isFullyVisible = rect.top >= viewportPadding &&
        rect.bottom <= window.innerHeight - viewportPadding &&
        rect.left >= 0 &&
        rect.right <= window.innerWidth;
    const isLargeTarget = rect.height >= window.innerHeight * 0.6;
    return isFixedLike || isFullyVisible || isLargeTarget;
}
function waitForNextFrame() {
    return new Promise((resolve) => {
        window.requestAnimationFrame(() => resolve());
    });
}
async function waitForScrollToFinish(element) {
    let stableFrames = 0;
    let previousRect = element.getBoundingClientRect();
    for (let frame = 0; frame < 30; frame++) {
        await waitForNextFrame();
        const currentRect = element.getBoundingClientRect();
        const moved = Math.abs(currentRect.top - previousRect.top) > 0.5 ||
            Math.abs(currentRect.left - previousRect.left) > 0.5;
        if (moved) {
            stableFrames = 0;
        }
        else {
            stableFrames += 1;
            if (stableFrames >= 2) {
                return;
            }
        }
        previousRect = currentRect;
    }
}
async function scrollElementForHighlight(element) {
    if (shouldSkipHighlightScroll(element)) {
        return;
    }
    element.scrollIntoView({
        behavior: "smooth",
        block: "nearest",
        inline: "nearest",
    });
    await waitForScrollToFinish(element);
}
// Highlight an element temporarily
export async function highlightElement(selector, duration = HIGHLIGHT_DURATION_MS) {
    const cssSelector = expandSelector(selector);
    const elements = getElementsForSelector(selector);
    if (elements.length === 0)
        return;
    if (cssSelector.startsWith("iframe:")) {
        const iframe = document.querySelector("iframe.page-iframe");
        const iframeRect = iframe?.getBoundingClientRect();
        if (elements[0]) {
            await scrollElementForHighlight(elements[0]);
        }
        elements.forEach((element) => {
            const elementRect = element.getBoundingClientRect();
            showHighlightOverlay(elementRect.left + (iframeRect?.left ?? 0), elementRect.top + (iframeRect?.top ?? 0), elementRect.width, elementRect.height, duration);
        });
        return;
    }
    if (elements[0]) {
        await scrollElementForHighlight(elements[0]);
    }
    elements.forEach((element) => {
        const rect = element.getBoundingClientRect();
        showHighlightOverlay(rect.left, rect.top, rect.width, rect.height, duration);
    });
}
// Check if an element is currently available in the DOM
function isElementAvailable(selector) {
    return getElementsForSelector(selector).length > 0;
}
// Create a temporary highlight overlay
function showHighlightOverlay(x, y, width, height, duration) {
    const padding = 4;
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;
    const rawLeft = x - padding;
    const rawTop = y - padding;
    const rawRight = x + width + padding;
    const rawBottom = y + height + padding;
    const left = Math.max(0, Math.min(rawLeft, viewportWidth));
    const top = Math.max(0, Math.min(rawTop, viewportHeight));
    const right = Math.max(0, Math.min(rawRight, viewportWidth));
    const bottom = Math.max(0, Math.min(rawBottom, viewportHeight));
    const clampedWidth = right - left;
    const clampedHeight = bottom - top;
    // Skip if target is fully outside the viewport after clamping.
    if (clampedWidth <= 0 || clampedHeight <= 0)
        return;
    const overlay = document.createElement("div");
    overlay.className = "selector-highlight-overlay";
    overlay.style.cssText = `
    position: fixed;
    left: ${left}px;
    top: ${top}px;
    width: ${clampedWidth}px;
    height: ${clampedHeight}px;
    border: 2px solid #3b82f6;
    border-radius: 4px;
    background: rgba(59, 130, 246, 0.1);
    pointer-events: none;
    z-index: 999999;
    animation: pulse-highlight 1s ease-in-out infinite;
    box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.2);
  `;
    // Add animation keyframes if not already added
    if (!document.querySelector("#selector-highlight-style")) {
        const style = document.createElement("style");
        style.id = "selector-highlight-style";
        style.textContent = `
      @keyframes pulse-highlight {
        0%, 100% { box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.2); }
        50% { box-shadow: 0 0 0 8px rgba(59, 130, 246, 0.1); }
      }
    `;
        document.head.appendChild(style);
    }
    document.body.appendChild(overlay);
    setTimeout(() => {
        overlay.remove();
    }, duration);
}
// Button component for "Show me" functionality with availability detection
function SelectorButton({ selectorDef, keyProp, }) {
    const editContext = useEditContext();
    const manualActions = editContext?.configuration.editor.manualActions;
    const availabilitySelector = selectorDef.availabilitySelector || selectorDef.selector;
    // For sidebar-only selectors, we don't need to check for an element
    const isSidebarOnly = selectorDef.isSidebarOnly;
    // Initialize to true for sidebar-only, false otherwise to avoid hydration mismatch
    // (document.querySelector doesn't exist during SSR)
    const [isAvailable, setIsAvailable] = useState(isSidebarOnly ? true : false);
    // Can open sidebar if: sidebar-only selector
    const canAutoOpenSidebar = Boolean(isSidebarOnly && editContext?.openSidebar && selectorDef.location);
    const hasBeforeAction = Boolean(selectorDef.beforeAction &&
        manualActions?.[selectorDef.beforeAction] &&
        editContext);
    const isActionable = isSidebarOnly
        ? canAutoOpenSidebar || hasBeforeAction
        : isAvailable || canAutoOpenSidebar || hasBeforeAction;
    // Monitor for element availability changes (skip for sidebar-only selectors)
    useEffect(() => {
        // Sidebar-only selectors are always "available" if openSidebar exists
        if (isSidebarOnly) {
            setIsAvailable(true);
            return;
        }
        // Initial check
        const initialAvailable = isElementAvailable(availabilitySelector);
        setIsAvailable(initialAvailable);
        // Set up MutationObserver to watch for DOM changes
        const checkAvailability = () => {
            const available = isElementAvailable(availabilitySelector);
            setIsAvailable(available);
        };
        // Watch the main document for changes
        const observer = new MutationObserver(checkAvailability);
        observer.observe(document.body, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ["data-testid", "class", "id"],
        });
        // Also watch the iframe if it exists (for iframe: selectors)
        let iframeObserver = null;
        const iframe = document.querySelector("iframe.page-iframe");
        if (iframe?.contentDocument?.body) {
            iframeObserver = new MutationObserver(checkAvailability);
            iframeObserver.observe(iframe.contentDocument.body, {
                childList: true,
                subtree: true,
                attributes: true,
                attributeFilter: ["data-testid", "class", "id"],
            });
        }
        // Also poll periodically as a fallback (iframe might load after mount)
        const intervalId = setInterval(checkAvailability, 1000);
        return () => {
            observer.disconnect();
            iframeObserver?.disconnect();
            clearInterval(intervalId);
        };
    }, [availabilitySelector, isSidebarOnly]);
    const tooltipText = isActionable
        ? selectorDef.description
        : selectorDef.notFoundMessage || selectorDef.description;
    return (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("button", { "aria-label": "Show me", onClick: async () => {
                        if (!isActionable)
                            return;
                        const runId = globalThis.crypto?.randomUUID?.() ??
                            `manual-${Date.now()}-${Math.random().toString(36).slice(2)}`;
                        const resolveElements = (selector = selectorDef.selector) => selector ? getElementsForSelector(selector) : [];
                        const runManualAction = async (actionName, elements) => {
                            if (!actionName || !editContext || !manualActions?.[actionName]) {
                                return;
                            }
                            const action = manualActions[actionName];
                            const actionProps = {
                                editContext,
                                selectorDef,
                                duration: HIGHLIGHT_DURATION_MS,
                                runId,
                                elements,
                                resolveElements,
                            };
                            await action(actionProps);
                        };
                        // If this selector is sidebar-only, open the sidebar before highlighting.
                        // For sidebar-only selectors, location is the sidebar ID (without -sidebar suffix)
                        if (selectorDef.isSidebarOnly &&
                            editContext?.openSidebar &&
                            selectorDef.location) {
                            const sidebarId = selectorDef.location;
                            const isSidebarAlreadyOpen = !!editContext.openSidebars?.includes(sidebarId);
                            if (!isSidebarAlreadyOpen) {
                                editContext.openSidebar(sidebarId);
                                // Give the sidebar a moment to render before querying/highlighting.
                                await new Promise((resolve) => setTimeout(resolve, 150));
                            }
                        }
                        const resolvedElements = !isSidebarOnly ? resolveElements() : [];
                        await runManualAction(selectorDef.beforeAction, resolvedElements);
                        // For sidebar-only selectors, we just open the sidebar (done above)
                        // For regular selectors, also highlight the element
                        if (!isSidebarOnly && selectorDef.selector) {
                            await highlightElement(selectorDef.selector, HIGHLIGHT_DURATION_MS);
                        }
                        if (selectorDef.afterAction) {
                            window.setTimeout(() => {
                                void runManualAction(selectorDef.afterAction, !isSidebarOnly ? resolveElements() : []);
                            }, HIGHLIGHT_DURATION_MS);
                        }
                    }, disabled: !isActionable, className: cn("inline-flex h-5 w-5 items-center justify-center rounded border transition-colors", isActionable
                        ? "cursor-pointer border-blue-200 bg-blue-50 text-blue-700 hover:bg-blue-100"
                        : "cursor-not-allowed border-gray-200 bg-gray-100 text-gray-400"), children: [_jsx(LocateFixed, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }), _jsx("span", { className: "sr-only", children: "Show me" })] }, keyProp) }), _jsx(TooltipContent, { children: tooltipText })] }));
}
// Render markdown content with clickable selectors
// Supports both {{selectorName}} syntax (looks up in uiSelectors) and legacy @selector syntax
function renderMarkdownWithSelectors(content, uiSelectors, manualLinkTargets, onManualLinkClick) {
    return (_jsx(MarkdownDisplay, { source: content, className: "space-y-0", components: manualMarkdownComponents, renderInline: (line) => renderLineWithSelectors(line, uiSelectors, manualLinkTargets, onManualLinkClick) }));
}
// Render a line with clickable selectors and basic formatting
// Supports: {{selectorName}} for named selectors, @selector for legacy direct selectors, **bold** text
// Parentheses around selectors (e.g., ({{name}})) are automatically hidden
function renderLineWithSelectors(text, uiSelectors, manualLinkTargets, onManualLinkClick) {
    if (!manualLinkTargets || !onManualLinkClick) {
        return renderInlineSelectorsAndFormatting(text, uiSelectors);
    }
    const parts = [];
    const linkRegex = /\[\[([^\]]+)\]\]/g;
    let lastIndex = 0;
    let match;
    while ((match = linkRegex.exec(text)) !== null) {
        const fullMatch = match[0] || "";
        const linkTitle = (match[1] || "").trim();
        if (match.index > lastIndex) {
            const prefix = text.substring(lastIndex, match.index);
            parts.push(_jsx(React.Fragment, { children: renderInlineSelectorsAndFormatting(prefix, uiSelectors) }, `text-${match.index}`));
        }
        const targetId = manualLinkTargets.get(linkTitle.toLowerCase());
        if (targetId) {
            parts.push(_jsx("button", { type: "button", onClick: () => onManualLinkClick(targetId), className: "cursor-pointer text-blue-600 underline decoration-blue-300 underline-offset-2 hover:text-blue-700", title: `Open "${linkTitle}"`, children: linkTitle }, `manual-link-${match.index}`));
        }
        else {
            parts.push(_jsx("span", { className: "text-orange-600", title: `Manual section not found: ${linkTitle}`, children: fullMatch }, `manual-link-missing-${match.index}`));
        }
        lastIndex = match.index + fullMatch.length;
    }
    if (lastIndex < text.length) {
        const suffix = text.substring(lastIndex);
        parts.push(_jsx(React.Fragment, { children: renderInlineSelectorsAndFormatting(suffix, uiSelectors) }, `suffix-${lastIndex}`));
    }
    return _jsx(_Fragment, { children: parts });
}
function renderInlineSelectorsAndFormatting(text, uiSelectors) {
    const parts = [];
    let lastIndex = 0;
    // Combined regex for {{namedSelector}}, @selector, and **bold**
    // Note: @selector can include -sidebar suffix for sidebar-only selectors
    // Also supports @iframe:selector syntax (iframe: is special and allowed)
    // Now also matches optional parentheses around selectors: ({{name}}) or (@selector)
    const regex = /(\()?(\{\{([\w\-]+)\}\})|(\()?(@(?:iframe:[\w\-\.#\[\]=]*[\w\-#\[\]=]|[\w\-\.#\[\]=]*[\w\-#\[\]=]))|(\*\*(.+?)\*\*)/g;
    let match;
    while ((match = regex.exec(text)) !== null) {
        // Check if there's an opening parenthesis before the selector
        const hasOpenParen = match[1] || match[4];
        const parenIndex = hasOpenParen ? match.index : -1;
        // Add text before the match (excluding opening paren if present)
        const textStart = lastIndex;
        const textEnd = hasOpenParen ? parenIndex : match.index;
        if (textEnd > textStart) {
            parts.push(text.substring(textStart, textEnd));
        }
        if (match[2] && match[3]) {
            // {{namedSelector}} match - look up in uiSelectors map
            const selectorName = match[3];
            const selectorDef = uiSelectors.get(selectorName);
            if (selectorDef) {
                // Check if there's a closing paren after this selector
                const afterMatch = match.index + match[0].length;
                const hasCloseParen = text[afterMatch] === ")";
                parts.push(_jsx(SelectorButton, { selectorDef: selectorDef, keyProp: match.index }, match.index));
                // Skip the closing paren if present
                if (hasCloseParen && hasOpenParen) {
                    lastIndex = afterMatch + 1;
                    regex.lastIndex = lastIndex;
                    continue;
                }
            }
            else {
                // Unknown selector, render as text (keep parens if present)
                parts.push(_jsxs("span", { className: "text-orange-600", title: "Unknown selector", children: [hasOpenParen ? "(" : "", selectorName, text[match.index + match[0].length] === ")" ? ")" : ""] }, match.index));
            }
        }
        else if (match[5]) {
            // @selector match (legacy direct selector syntax) - create ad-hoc selector def
            const selectorToken = match[5];
            const parsed = parseSelectorToken(selectorToken);
            const selectorName = selectorToken.replace(/^@/, "");
            const registeredSelectorDef = uiSelectors.get(selectorName);
            const effectiveSelectorDef = registeredSelectorDef ?? {
                name: selectorToken,
                selector: parsed.selector,
                description: parsed.isSidebarOnly
                    ? `Open ${parsed.location?.replace(/-sidebar$/, "").replace(/-/g, " ")} panel`
                    : expandSelector(selectorToken),
                location: parsed.location,
                isSidebarOnly: parsed.isSidebarOnly,
            };
            // Check if there's a closing paren after this selector
            const afterMatch = match.index + match[0].length;
            const hasCloseParen = text[afterMatch] === ")";
            parts.push(_jsx(SelectorButton, { selectorDef: effectiveSelectorDef, keyProp: match.index }, match.index));
            // Skip the closing paren if present
            if (hasCloseParen && hasOpenParen) {
                lastIndex = afterMatch + 1;
                regex.lastIndex = lastIndex;
                continue;
            }
        }
        else if (match[6]) {
            // **bold** match
            parts.push(_jsx("strong", { children: match[7] }, match.index));
        }
        lastIndex = match.index + match[0].length;
    }
    // Add remaining text
    if (lastIndex < text.length) {
        parts.push(text.substring(lastIndex));
    }
    return _jsx(_Fragment, { children: parts });
}
function findTocPath(sections, targetId, ancestors = []) {
    for (const section of sections) {
        const nextAncestors = [...ancestors, section];
        if (section.id === targetId)
            return nextAncestors;
        if (section.children && section.children.length > 0) {
            const path = findTocPath(section.children, targetId, nextAncestors);
            if (path)
                return path;
        }
    }
    return null;
}
function isDirectlyNavigableSection(section) {
    return !!section.hasContent || section.children.length === 0;
}
function resolveFirstNavigableSection(section) {
    if (isDirectlyNavigableSection(section) || section.children.length === 0) {
        return section;
    }
    return resolveFirstNavigableSection(section.children[0]);
}
function resolveSelectedSectionId(sections, targetId) {
    const path = findTocPath(sections, targetId);
    const targetSection = path?.[path.length - 1];
    if (!targetSection)
        return targetId;
    return resolveFirstNavigableSection(targetSection).id;
}
function findNearestNavigableAncestor(path) {
    if (!path || path.length < 2)
        return null;
    for (let i = path.length - 2; i >= 0; i -= 1) {
        const section = path[i];
        if (section && isDirectlyNavigableSection(section)) {
            return section;
        }
    }
    return null;
}
const SECTION_THEMES = {
    "getting started": {
        icon: Rocket,
        color: "text-emerald-600",
        bg: "bg-emerald-50",
        border: "border-emerald-100",
        accent: "bg-emerald-500",
    },
    "page editing": {
        icon: FileEdit,
        color: "text-blue-600",
        bg: "bg-blue-50",
        border: "border-blue-100",
        accent: "bg-blue-500",
    },
    "managing content": {
        icon: BookOpen,
        color: "text-amber-600",
        bg: "bg-amber-50",
        border: "border-amber-100",
        accent: "bg-amber-500",
    },
    "ai assistant": {
        icon: BookOpen,
        color: "text-violet-600",
        bg: "bg-violet-50",
        border: "border-violet-100",
        accent: "bg-violet-500",
    },
};
const DEFAULT_THEME = {
    icon: BookOpen,
    color: "text-violet-600",
    bg: "bg-violet-50",
    border: "border-violet-100",
    accent: "bg-violet-500",
};
function getSectionTheme(title) {
    if (!title)
        return DEFAULT_THEME;
    return SECTION_THEMES[title.toLowerCase()] ?? DEFAULT_THEME;
}
function TocSectionCard({ section, onSelect, onToggleCollapse, isCollapsed, }) {
    const theme = getSectionTheme(section.title);
    const Icon = theme.icon;
    const hasChildren = !!(section.children && section.children.length > 0);
    return (_jsxs("div", { className: "group", children: [_jsx("button", { type: "button", onClick: () => onSelect(section.id), className: cn("w-full rounded-lg p-3 text-left transition-all", "bg-white hover:bg-gray-50/50"), children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("div", { className: cn("flex h-9 w-9 shrink-0 items-center justify-center rounded-lg", theme.bg), children: section.svgIcon ? (_jsx(SvgIcon, { svg: section.svgIcon, size: 24, className: theme.color })) : (_jsx(Icon, { className: cn("h-[18px] w-[18px]", theme.color), strokeWidth: 1.75 })) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-sm font-semibold text-gray-900", children: section.title || "Untitled" }) }), section.summary && (_jsx("p", { className: "mt-0.5 line-clamp-2 text-xs leading-relaxed text-gray-500", children: section.summary }))] })] }) }), hasChildren && (_jsxs("div", { className: "mt-1", children: [_jsxs("button", { type: "button", onClick: () => onToggleCollapse(section.id), className: "ml-[60px] flex w-fit items-center gap-1.5 rounded-md py-1 text-xs text-gray-400 transition-colors hover:text-gray-600", children: [_jsx(ChevronRight, { className: cn("h-3 w-3 shrink-0 transition-transform", !isCollapsed && "rotate-90") }), _jsx("span", { children: isCollapsed ? "Show articles" : "Hide articles" })] }), !isCollapsed && (_jsx("div", { className: "mt-0.5 ml-[60px] space-y-px border-l-2 border-gray-100 pl-3", children: section.children.map((child) => (_jsxs("button", { type: "button", onClick: () => onSelect(child.id), className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm text-gray-600 transition-colors hover:bg-gray-50 hover:text-gray-900", children: [_jsx("span", { className: cn("h-1.5 w-1.5 shrink-0 rounded-full", theme.accent, "opacity-40 transition-opacity group-hover:opacity-70") }), _jsx("span", { className: "truncate", children: child.title || "Untitled" })] }, child.id))) }))] }))] }));
}
function renderTocTree(sections, onSelect, onToggleCollapse, collapsedSectionIds, depth = 0) {
    if (depth === 0) {
        return (_jsx("div", { className: "space-y-3", children: sections.map((section) => {
                const isCollapsed = collapsedSectionIds.has(section.id);
                return (_jsx(TocSectionCard, { section: section, onSelect: onSelect, onToggleCollapse: onToggleCollapse, isCollapsed: isCollapsed }, section.id));
            }) }));
    }
    return (_jsx("div", { className: cn(depth > 0 && "ml-3 border-l border-gray-100 pl-2"), children: sections.map((section) => {
            const hasChildren = !!(section.children && section.children.length > 0);
            const isCollapsed = hasChildren && collapsedSectionIds.has(section.id);
            return (_jsxs("div", { className: "my-0.5", children: [_jsxs("div", { className: cn("group flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 transition-colors hover:bg-gray-50", "text-sm text-gray-500 hover:text-gray-700"), children: [hasChildren ? (_jsx("button", { type: "button", onClick: () => onToggleCollapse(section.id), className: "rounded p-0.5 text-gray-300 transition-colors hover:bg-gray-100 hover:text-gray-500", "aria-label": isCollapsed
                                    ? `Expand ${section.title || "section"}`
                                    : `Collapse ${section.title || "section"}`, title: isCollapsed ? "Expand section" : "Collapse section", children: _jsx(ChevronRight, { className: cn("h-3.5 w-3.5 shrink-0 transition-transform", !isCollapsed && "rotate-90") }) })) : (_jsx("span", { className: "h-3.5 w-3.5 shrink-0" })), _jsx("button", { type: "button", onClick: () => onSelect(section.id), className: "flex-1 text-left", children: section.title || "Untitled" })] }), hasChildren &&
                        !isCollapsed &&
                        renderTocTree(section.children, onSelect, onToggleCollapse, collapsedSectionIds, depth + 1)] }, section.id));
        }) }));
}
function buildChapterOptions(chapter) {
    const result = [];
    const walk = (sections, depth) => {
        for (const section of sections) {
            result.push({ section, depth });
            if (section.children.length > 0) {
                walk(section.children, depth + 1);
            }
        }
    };
    // Include the chapter itself if it has content, then its children
    if (isDirectlyNavigableSection(chapter)) {
        result.push({ section: chapter, depth: 0 });
    }
    walk(chapter.children, isDirectlyNavigableSection(chapter) ? 1 : 0);
    return result;
}
function InChapterDropdown({ toc, currentTocPath, selectedSectionId, onSelect, }) {
    const chapter = currentTocPath?.[0] ?? null;
    const chapterOptions = useMemo(() => (chapter ? buildChapterOptions(chapter) : []), [chapter]);
    const allChapters = useMemo(() => toc, [toc]);
    // Don't render if there's no chapter or only one page in it
    if (!chapter || chapterOptions.length <= 1)
        return null;
    const selectedTitle = chapterOptions.find((o) => o.section.id === selectedSectionId)?.section.title;
    return (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsxs("button", { type: "button", className: "inline-flex w-full items-center justify-between gap-2 rounded-md border border-gray-200 bg-white px-2.5 py-1.5 text-xs transition-colors hover:bg-gray-50", children: [_jsxs("span", { className: "truncate text-gray-500", children: [_jsx("span", { className: "font-medium text-gray-700", children: selectedTitle ?? chapter.title }), " ", _jsxs("span", { className: "text-gray-400", children: ["\u2014 in ", chapter.title] })] }), _jsx(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 text-gray-400" })] }) }), _jsxs(DropdownMenuContent, { align: "start", className: "max-h-80 w-[--radix-dropdown-menu-trigger-width] overflow-y-auto", children: [allChapters.length > 0 && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuLabel, { className: "text-[11px] font-semibold tracking-wide text-gray-400 uppercase", children: "Chapters" }), allChapters.map((c) => {
                                const isCurrent = c.id === chapter?.id;
                                const theme = getSectionTheme(c.title);
                                const Icon = theme.icon;
                                return (_jsxs(DropdownMenuItem, { onClick: () => !isCurrent && onSelect(c.id), className: cn(isCurrent && "bg-blue-50 font-medium"), children: [c.svgIcon ? (_jsx(SvgIcon, { svg: c.svgIcon, size: 14, className: cn("mr-1.5 shrink-0", theme.color) })) : (_jsx(Icon, { className: cn("mr-1.5 h-3.5 w-3.5 shrink-0", theme.color), strokeWidth: 1.75 })), _jsx("span", { className: "truncate", children: c.title })] }, c.id));
                            }), _jsx(DropdownMenuSeparator, {}), _jsxs(DropdownMenuLabel, { className: "text-[11px] font-semibold tracking-wide text-gray-400 uppercase", children: ["In ", chapter.title] })] })), chapterOptions.map(({ section, depth }) => {
                        const isActive = section.id === selectedSectionId;
                        const navigable = isDirectlyNavigableSection(section);
                        return (_jsx(DropdownMenuItem, { disabled: !navigable, onClick: () => navigable && onSelect(section.id), className: cn(isActive && "bg-blue-50 font-medium", !navigable && "pointer-events-none opacity-60"), style: { paddingLeft: `${8 + depth * 16}px` }, children: _jsx("span", { className: "truncate", children: section.title || "Untitled" }) }, section.id));
                    })] })] }));
}
function flattenSections(sections) {
    const flattened = [];
    for (const section of sections) {
        flattened.push(section);
        if (section.children && section.children.length > 0) {
            flattened.push(...flattenSections(section.children));
        }
    }
    return flattened;
}
function flattenNavigableSections(sections) {
    const flattened = [];
    for (const section of sections) {
        if (isDirectlyNavigableSection(section)) {
            flattened.push(section);
        }
        if (section.children.length > 0) {
            flattened.push(...flattenNavigableSections(section.children));
        }
    }
    return flattened;
}
const MANUAL_SECTION_TEMPLATE_ID = "c5f1e8a2-9b50-4fe2-9b6d-3db00c3b3b8a";
export function ManualBrowser({ onClose }) {
    const editContext = useEditContext();
    const [toc, setToc] = useState([]);
    const selectedSectionId = editContext?.selectedHelpSectionId ?? null;
    const [currentSection, setCurrentSection] = useState(null);
    const currentSectionRef = useRef(null);
    const [loadingToc, setLoadingToc] = useState(false);
    const [loadingSection, setLoadingSection] = useState(false);
    const [error, setError] = useState(null);
    const [searchQuery, setSearchQuery] = useState("");
    const [searchResults, setSearchResults] = useState([]);
    const [searching, setSearching] = useState(false);
    const [collapsedTocSectionIds, setCollapsedTocSectionIds] = useState(() => new Set());
    const [manualBackHistory, setManualBackHistory] = useState([]);
    // Track revision to force re-fetch (incremented when websocket notifies of changes)
    const [sectionRevision, setSectionRevision] = useState(0);
    // Keep a ref to all TOC item IDs for checking if changed item is in the manual
    const tocItemIdsRef = useRef(new Set());
    const manualBackHistoryRef = useRef([]);
    const historyNavigationModeRef = useRef(null);
    const lastObservedSelectedSectionIdRef = useRef(undefined);
    // Keep a ref to selectedSectionId to avoid stale closures in websocket callback
    const selectedSectionIdRef = useRef(null);
    const currentTocPath = useMemo(() => {
        if (!selectedSectionId)
            return null;
        return findTocPath(toc, selectedSectionId);
    }, [toc, selectedSectionId]);
    const parentTocSection = useMemo(() => {
        return findNearestNavigableAncestor(currentTocPath);
    }, [currentTocPath]);
    const chapterNavigation = useMemo(() => {
        if (!selectedSectionId)
            return { previous: null, next: null };
        const flatSections = flattenNavigableSections(toc);
        const currentIndex = flatSections.findIndex((section) => section.id === selectedSectionId);
        if (currentIndex < 0)
            return { previous: null, next: null };
        return {
            previous: currentIndex > 0 ? flatSections[currentIndex - 1] : null,
            next: currentIndex < flatSections.length - 1
                ? flatSections[currentIndex + 1]
                : null,
        };
    }, [toc, selectedSectionId]);
    const manualLinkTargets = useMemo(() => {
        const lookup = new Map();
        const sections = flattenSections(toc);
        for (const section of sections) {
            const key = section.title?.trim().toLowerCase();
            if (key && !lookup.has(key)) {
                lookup.set(key, resolveFirstNavigableSection(section).id);
            }
        }
        return lookup;
    }, [toc]);
    const manualSectionsById = useMemo(() => {
        const map = new Map();
        const sections = flattenSections(toc);
        for (const section of sections) {
            map.set(section.id.toLowerCase(), section);
        }
        return map;
    }, [toc]);
    const backTargetSectionId = manualBackHistory.length > 0
        ? manualBackHistory[manualBackHistory.length - 1]
        : null;
    const backTargetSection = useMemo(() => {
        if (!backTargetSectionId)
            return null;
        return manualSectionsById.get(backTargetSectionId.toLowerCase()) ?? null;
    }, [backTargetSectionId, manualSectionsById]);
    const backButtonLabel = backTargetSection?.title
        ? `Back to ${backTargetSection.title}`
        : "Back to contents";
    const backButtonText = backTargetSectionId === null ? "Contents" : "Back";
    // Keep selectedSectionId ref in sync
    useEffect(() => {
        selectedSectionIdRef.current = selectedSectionId;
    }, [selectedSectionId]);
    useEffect(() => {
        currentSectionRef.current = currentSection;
    }, [currentSection]);
    useEffect(() => {
        manualBackHistoryRef.current = manualBackHistory;
    }, [manualBackHistory]);
    useEffect(() => {
        const previousSelectedSectionId = lastObservedSelectedSectionIdRef.current;
        if (previousSelectedSectionId === undefined) {
            lastObservedSelectedSectionIdRef.current = selectedSectionId;
            return;
        }
        const normalizedPreviousSelectedSectionId = previousSelectedSectionId && toc.length > 0
            ? resolveSelectedSectionId(toc, previousSelectedSectionId)
            : previousSelectedSectionId;
        const normalizedSelectedSectionId = selectedSectionId && toc.length > 0
            ? resolveSelectedSectionId(toc, selectedSectionId)
            : selectedSectionId;
        if (normalizedPreviousSelectedSectionId === normalizedSelectedSectionId) {
            lastObservedSelectedSectionIdRef.current = selectedSectionId;
            return;
        }
        if (historyNavigationModeRef.current === "back") {
            historyNavigationModeRef.current = null;
        }
        else {
            setManualBackHistory((prev) => [
                ...prev,
                normalizedPreviousSelectedSectionId,
            ]);
        }
        lastObservedSelectedSectionIdRef.current = selectedSectionId;
    }, [selectedSectionId, toc]);
    useEffect(() => {
        if (!selectedSectionId || !editContext || toc.length === 0)
            return;
        const resolvedSectionId = resolveSelectedSectionId(toc, selectedSectionId);
        if (resolvedSectionId !== selectedSectionId) {
            editContext.setSelectedHelpSectionId(resolvedSectionId);
        }
    }, [editContext, selectedSectionId, toc]);
    // Build set of all TOC item IDs (for websocket matching)
    useEffect(() => {
        const collectIds = (sections) => {
            const ids = [];
            for (const section of sections) {
                ids.push(section.id);
                if (section.children) {
                    ids.push(...collectIds(section.children));
                }
            }
            return ids;
        };
        tocItemIdsRef.current = new Set(collectIds(toc));
    }, [toc]);
    // Load TOC on mount
    useEffect(() => {
        setLoadingToc(true);
        setError(null);
        loadManualToc()
            .then((data) => {
            setToc(data);
        })
            .catch((err) => {
            console.error("Failed to load manual TOC:", err);
            setError("Failed to load manual");
        })
            .finally(() => {
            setLoadingToc(false);
        });
    }, []);
    // Load section content when selection changes or revision changes
    useEffect(() => {
        let cancelled = false;
        if (!selectedSectionId) {
            setCurrentSection(null);
            setLoadingSection(false);
            return;
        }
        const resolvedSectionId = toc.length > 0
            ? resolveSelectedSectionId(toc, selectedSectionId)
            : selectedSectionId;
        if (resolvedSectionId !== selectedSectionId) {
            return () => {
                cancelled = true;
            };
        }
        // Only show loading spinner if we don't have current section (initial load)
        // For refreshes, keep showing the old content to avoid flicker
        const isInitialLoad = !currentSectionRef.current ||
            currentSectionRef.current.id !== selectedSectionId;
        if (isInitialLoad) {
            setLoadingSection(true);
        }
        loadManualSection(resolvedSectionId)
            .then((data) => {
            if (cancelled)
                return;
            setCurrentSection(data);
            setLoadingSection(false);
        })
            .catch((err) => {
            if (cancelled)
                return;
            console.error("Failed to load section:", err);
            setCurrentSection(null);
            setLoadingSection(false);
        });
        return () => {
            cancelled = true;
        };
    }, [sectionRevision, selectedSectionId, toc]);
    // Search manual sections using internal search (SQL + AI providers).
    useEffect(() => {
        let cancelled = false;
        const trimmedQuery = searchQuery.trim();
        if (!trimmedQuery || !editContext) {
            setSearching(false);
            setSearchResults([]);
            return;
        }
        const timeoutId = window.setTimeout(async () => {
            setSearching(true);
            try {
                const result = await executeSearch({
                    query: `${trimmedQuery}|template:${MANUAL_SECTION_TEMPLATE_ID}`,
                    editContext,
                    maxResults: 20,
                    index: "master",
                    skipValidation: true,
                });
                if (cancelled)
                    return;
                if (result.type === "success") {
                    const items = result.data || [];
                    const mapped = items
                        .map((item) => manualSectionsById.get(String(item.id || "").toLowerCase()))
                        .filter((section) => !!section);
                    const unique = Array.from(new Map(mapped.map((section) => [section.id, section])).values());
                    setSearchResults(unique);
                }
                else {
                    console.error("Failed to search manual", result.response.statusText);
                    setSearchResults([]);
                }
            }
            catch (err) {
                if (!cancelled) {
                    console.error("Manual search failed", err);
                    setSearchResults([]);
                }
            }
            finally {
                if (!cancelled) {
                    setSearching(false);
                }
            }
        }, 300);
        return () => {
            cancelled = true;
            window.clearTimeout(timeoutId);
        };
    }, [searchQuery, editContext, manualSectionsById]);
    // Listen for websocket messages to auto-refresh when manual items change
    // Use ref for selectedSectionId to avoid stale closures and only re-register when selection actually changes
    useEffect(() => {
        const addListener = editContext?.addSocketMessageListener;
        if (!addListener)
            return;
        const removeListener = addListener((message) => {
            if (message.type === "item-changed") {
                const changedItemId = message.payload?.item?.id;
                const currentSelectedId = selectedSectionIdRef.current; // Use ref to get latest value
                // Check if the changed item is the currently selected section (using ref for latest value)
                if (changedItemId && changedItemId === currentSelectedId) {
                    // Invalidate cache for this section to ensure fresh data is fetched
                    invalidateManualSectionCache(changedItemId);
                    // Bump revision to trigger re-fetch of current section
                    setSectionRevision((r) => r + 1);
                }
                // Also check if any item in the TOC was changed (could affect TOC structure)
                if (changedItemId && tocItemIdsRef.current.has(changedItemId)) {
                    // Reload TOC if a manual item was changed (might have new children, title change, etc.)
                    loadManualToc()
                        .then((data) => {
                        setToc(data);
                    })
                        .catch((err) => {
                        console.error("Failed to reload manual TOC:", err);
                    });
                }
            }
        });
        return removeListener;
    }, [selectedSectionId]); // Only re-register when selectedSectionId changes, not when editContext object changes
    const handleSelectSection = useCallback((id) => {
        if (!editContext)
            return;
        editContext.setSelectedHelpSectionId(resolveSelectedSectionId(toc, id));
    }, [editContext, toc]);
    const handleSelectSearchResult = useCallback((id) => {
        if (!editContext)
            return;
        editContext.setSelectedHelpSectionId(resolveSelectedSectionId(toc, id));
        setSearchQuery("");
        setSearchResults([]);
    }, [editContext, toc]);
    const handleToggleTocSection = useCallback((id) => {
        setCollapsedTocSectionIds((prev) => {
            const next = new Set(prev);
            if (next.has(id)) {
                next.delete(id);
            }
            else {
                next.add(id);
            }
            return next;
        });
    }, []);
    const normalizeHistorySectionId = useCallback((id) => {
        if (!id || toc.length === 0)
            return id;
        return resolveSelectedSectionId(toc, id);
    }, [toc]);
    const handleGoBack = useCallback(() => {
        if (!editContext || !selectedSectionId)
            return;
        const history = manualBackHistoryRef.current;
        const previousSectionId = history.length > 0 ? history[history.length - 1] : null;
        historyNavigationModeRef.current = "back";
        setManualBackHistory((prev) => prev.length > 0 ? prev.slice(0, -1) : prev);
        editContext.setSelectedHelpSectionId(normalizeHistorySectionId(previousSectionId));
    }, [editContext, normalizeHistorySectionId, selectedSectionId]);
    if (loadingToc) {
        return (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx(Loader2, { className: "h-5 w-5 animate-spin text-gray-400" }) }));
    }
    if (error) {
        return (_jsx("div", { className: "px-4 py-8 text-center text-sm text-red-500", children: error }));
    }
    if (toc.length === 0) {
        return (_jsxs("div", { className: "px-4 py-8 text-center text-sm text-gray-500", children: [_jsx(Book, { className: "mx-auto mb-2 h-8 w-8 text-gray-300" }), _jsx("p", { children: "No manual content available yet." })] }));
    }
    return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "shrink-0 border-b border-gray-200/60 bg-linear-to-b from-gray-50 to-white px-4 py-3", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-lg bg-blue-50", children: _jsx(Book, { className: "h-4 w-4 text-blue-600", strokeWidth: 1.75 }) }), _jsx("h2", { className: "text-base font-semibold text-gray-900", children: "User Manual" })] }), onClose && (_jsx("button", { onClick: onClose, className: "shrink-0 rounded p-1 text-gray-400 transition-colors hover:bg-gray-200 hover:text-gray-600", "aria-label": "Close", children: _jsx(X, { size: 16, strokeWidth: 1.5 }) }))] }), _jsx("div", { className: "mt-2", children: _jsx(FilterInput, { value: searchQuery, onChange: setSearchQuery, placeholder: "Search manual pages...", size: "xs", loading: searching }) }), selectedSectionId && (_jsx("div", { className: "mt-2", children: _jsx(InChapterDropdown, { toc: toc, currentTocPath: currentTocPath, selectedSectionId: selectedSectionId, onSelect: handleSelectSection }) })), searchQuery.trim().length > 0 && (_jsx("div", { className: "mt-2 max-h-52 overflow-y-auto rounded-lg border border-gray-200 bg-white shadow-sm", children: searching ? (_jsxs("div", { className: "flex items-center gap-2 px-3 py-3 text-xs text-gray-500", children: [_jsx(Loader2, { className: "h-3 w-3 animate-spin" }), "Searching manual..."] })) : searchResults.length > 0 ? (searchResults.map((section) => (_jsxs("button", { type: "button", onClick: () => handleSelectSearchResult(section.id), className: "group block w-full border-b border-gray-50 px-3 py-2.5 text-left transition-colors last:border-b-0 hover:bg-blue-50/50", children: [_jsx("span", { className: "block text-sm font-medium text-gray-900 transition-colors group-hover:text-blue-700", children: section.title || "Untitled" }), section.summary && (_jsx("span", { className: "mt-0.5 line-clamp-2 block text-xs leading-relaxed text-gray-500", children: section.summary }))] }, section.id)))) : (_jsx("div", { className: "px-3 py-3 text-center text-xs text-gray-500", children: "No manual pages matched your search." })) }))] }), _jsx("div", { className: "flex-1 overflow-y-auto p-4 select-text", children: loadingSection ? (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx(Loader2, { className: "h-5 w-5 animate-spin text-gray-400" }) })) : !selectedSectionId ? (_jsx("div", { children: renderTocTree(toc, handleSelectSection, handleToggleTocSection, collapsedTocSectionIds) })) : currentSection ? (_jsxs("div", { children: [_jsxs("div", { className: "mb-1 flex items-center justify-between", children: [_jsxs("button", { type: "button", onClick: handleGoBack, className: "inline-flex shrink-0 items-center gap-1 rounded px-2 py-1 text-sm text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900", "aria-label": backButtonLabel, title: backButtonLabel, children: [_jsx(ArrowLeft, { className: "h-4 w-4" }), _jsx("span", { className: "hidden sm:inline", children: backButtonText })] }), editContext?.user?.isAdministrator && editContext?.loadItem && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("button", { type: "button", onClick: async (e) => {
                                                    e.preventDefault();
                                                    e.stopPropagation();
                                                    if (!editContext?.loadItem) {
                                                        console.warn("loadItem not available");
                                                        return;
                                                    }
                                                    try {
                                                        const language = editContext?.currentItemDescriptor?.language ||
                                                            editContext?.item?.language ||
                                                            "en";
                                                        console.log("Loading manual section:", currentSection.id, language);
                                                        const result = await editContext.loadItem({
                                                            id: currentSection.id,
                                                            language: language,
                                                            version: 0,
                                                        }, { addToBrowseHistory: true });
                                                        console.log("Load result:", result);
                                                    }
                                                    catch (error) {
                                                        console.error("Failed to load manual section:", error);
                                                    }
                                                }, className: "shrink-0 rounded p-1.5 text-gray-500 transition-colors hover:bg-gray-100 hover:text-gray-700", "aria-label": "Edit item", title: "Edit item", children: _jsx(Edit, { className: "h-4 w-4" }) }) }), _jsx(TooltipContent, { children: "Edit item" })] }))] }), _jsxs("h2", { className: "my-2 flex items-center gap-2 text-xl font-bold text-gray-900", children: [currentSection.svgIcon && (_jsx(SvgIcon, { svg: currentSection.svgIcon, size: 24, className: "shrink-0 text-gray-500" })), currentSection.title] }), currentSection.summary &&
                            (() => {
                                const theme = parentTocSection
                                    ? getSectionTheme(parentTocSection.title)
                                    : getSectionTheme(currentSection.title);
                                return (_jsx("p", { className: cn("my-4 mb-8 border-l-2 pl-3 text-sm text-gray-500 italic", theme.border), children: currentSection.summary }));
                            })(), _jsx("div", { className: "prose prose-sm max-w-none select-text", children: renderMarkdownWithSelectors(currentSection.content || "", parseUiSelectors(currentSection.uiSelectors), manualLinkTargets, handleSelectSection) }), currentSection.subsections &&
                            currentSection.subsections.length > 0 && (_jsxs("div", { className: "mt-8 border-t border-gray-100 pt-4", children: [_jsx("h3", { className: "mb-3 text-[11px] font-bold tracking-widest text-gray-400 uppercase", children: "In this section" }), _jsx("div", { className: "space-y-0.5", children: currentSection.subsections.map((subsection) => {
                                        const theme = getSectionTheme(currentSection.title);
                                        return (_jsxs("button", { onClick: () => handleSelectSection(subsection.id), className: "group flex w-full items-center gap-2.5 rounded-lg px-3 py-2 text-left text-sm text-gray-600 transition-all hover:bg-gray-50 hover:text-gray-900", children: [_jsx("span", { className: cn("h-1.5 w-1.5 shrink-0 rounded-full transition-transform group-hover:scale-125", theme.accent, "opacity-50 group-hover:opacity-80") }), _jsx("span", { className: "flex-1 truncate font-medium", children: subsection.title }), _jsx(ChevronRight, { className: "h-3.5 w-3.5 shrink-0 text-gray-300 transition-colors group-hover:text-gray-500" })] }, subsection.id));
                                    }) })] }))] })) : (_jsx("div", { className: "py-8 text-center text-sm text-gray-500", children: "Select a section to view its content" })) }), selectedSectionId &&
                currentSection &&
                (chapterNavigation.previous || chapterNavigation.next) && (_jsx("div", { className: "shrink-0 border-t border-gray-200/60 bg-white px-4 py-3", children: _jsxs("div", { className: "grid grid-cols-2 gap-2", children: [chapterNavigation.previous ? (_jsxs("button", { type: "button", onClick: () => chapterNavigation.previous &&
                                handleSelectSection(chapterNavigation.previous.id), className: "group rounded-lg border border-gray-200 px-3 py-2 text-left transition-all hover:border-blue-200 hover:bg-blue-50/30", children: [_jsxs("span", { className: "mb-0.5 inline-flex items-center gap-1 text-xs font-medium text-gray-400 transition-colors group-hover:text-blue-500", children: [_jsx(ArrowLeft, { className: "h-3 w-3" }), "Previous"] }), _jsx("span", { className: "block truncate text-sm font-medium text-gray-700 transition-colors group-hover:text-gray-900", children: chapterNavigation.previous.title })] })) : (_jsx("div", {})), chapterNavigation.next ? (_jsxs("button", { type: "button", onClick: () => chapterNavigation.next &&
                                handleSelectSection(chapterNavigation.next.id), className: "group rounded-lg border border-gray-200 px-3 py-2 text-right transition-all hover:border-blue-200 hover:bg-blue-50/30", children: [_jsxs("span", { className: "mb-0.5 inline-flex items-center justify-end gap-1 text-xs font-medium text-gray-400 transition-colors group-hover:text-blue-500", children: ["Next", _jsx(ArrowRight, { className: "h-3 w-3" })] }), _jsx("span", { className: "block truncate text-sm font-medium text-gray-700 transition-colors group-hover:text-gray-900", children: chapterNavigation.next.title })] })) : (_jsx("div", {}))] }) }))] }));
}
//# sourceMappingURL=ManualBrowser.js.map