import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
import { FileCode2, Plus, RefreshCw, Search, ShieldAlert, Trash2 } from "lucide-react";
import { toast } from "sonner";
import { Button } from "../../../components/ui/button";
import { Input } from "../../../components/ui/input";
import { cn } from "../../../lib/utils";
import { useEditContext } from "../../client/editContext";
import { Splitter } from "../../ui/Splitter";
import { updateAgentContext } from "../../services/agentService";
import { setupWizardService, } from "../../../setup/services/setupWizardService";
import { JavaScriptToolConfigPanel } from "./JavaScriptToolConfigPanel";
import { JavaScriptToolAgentPanel } from "./JavaScriptToolAgentPanel";
import { CreateJavaScriptToolDialog } from "./CreateJavaScriptToolDialog";
const JAVA_SCRIPT_TOOL_ROOT_PATHS = [
    "/sitecore/system/parhelia/settings/ai tools/scripts",
];
const JAVA_SCRIPT_TOOL_EXTERNAL_REFRESH_DEBOUNCE_MS = 350;
function isJavaScriptToolItemChange(changes, selectedToolId) {
    const normalizedSelectedToolId = selectedToolId?.toLowerCase() ?? null;
    return changes.some((change) => {
        const itemId = change.item?.id?.trim().toLowerCase();
        if (normalizedSelectedToolId && itemId === normalizedSelectedToolId) {
            return false;
        }
        const path = change.item?.path?.trim().toLowerCase();
        if (path &&
            JAVA_SCRIPT_TOOL_ROOT_PATHS.some((root) => path.startsWith(root))) {
            return true;
        }
        return false;
    });
}
function buildJavaScriptToolAgentContext(toolId) {
    return {
        activeWorkspace: "settings",
        currentItemId: toolId,
        additionalData: {
            activeWorkspace: "settings",
            javaScriptToolEditor: true,
            javaScriptToolId: toolId,
        },
    };
}
export function JavaScriptToolsPanel() {
    const editContext = useEditContext();
    const [state, setState] = useState("loading");
    const [tools, setTools] = useState([]);
    const [error, setError] = useState(null);
    const [searchQuery, setSearchQuery] = useState("");
    const [selectedToolId, setSelectedToolId] = useState(null);
    const [showCreateDialog, setShowCreateDialog] = useState(false);
    const [deleting, setDeleting] = useState(false);
    const [agentId, setAgentId] = useState(null);
    const [agentLoading, setAgentLoading] = useState(false);
    const [agentResetting, setAgentResetting] = useState(false);
    const [agentError, setAgentError] = useState(null);
    const selectedToolIdRef = useRef(null);
    const loadToolsRef = useRef(null);
    const externalRefreshTimeoutRef = useRef(null);
    useEffect(() => {
        selectedToolIdRef.current = selectedToolId;
    }, [selectedToolId]);
    const filteredTools = useMemo(() => {
        const query = searchQuery.trim().toLowerCase();
        if (!query) {
            return tools;
        }
        return tools.filter((tool) => {
            return (tool.name.toLowerCase().includes(query) ||
                tool.path.toLowerCase().includes(query) ||
                (tool.description ?? "").toLowerCase().includes(query));
        });
    }, [searchQuery, tools]);
    const selectedTool = useMemo(() => tools.find((tool) => tool.id === selectedToolId) ?? null, [selectedToolId, tools]);
    const loadTools = useCallback(async (preferredToolId) => {
        try {
            setState("loading");
            setError(null);
            const loadedTools = await setupWizardService.getJavaScriptTools();
            setTools(loadedTools);
            const resolvedSelection = loadedTools.find((tool) => tool.id === preferredToolId)?.id ??
                loadedTools.find((tool) => tool.id === selectedToolIdRef.current)?.id ??
                null;
            setSelectedToolId(resolvedSelection);
            setState("success");
        }
        catch (loadError) {
            setState("error");
            setError(loadError instanceof Error
                ? loadError.message
                : "Failed to load JavaScript tools");
            setTools([]);
            setSelectedToolId(null);
        }
    }, []);
    loadToolsRef.current = loadTools;
    useEffect(() => {
        void loadTools();
    }, [loadTools]);
    const syncAgentContext = useCallback(async (nextAgentId, toolId) => {
        try {
            await updateAgentContext(nextAgentId, buildJavaScriptToolAgentContext(toolId));
        }
        catch (contextError) {
            setAgentError(contextError instanceof Error
                ? `Failed to update JavaScript tool assistant context: ${contextError.message}`
                : "Failed to update JavaScript tool assistant context");
        }
    }, []);
    const selectedToolIdentity = selectedTool?.id ?? null;
    useEffect(() => {
        let cancelled = false;
        if (!selectedToolIdentity) {
            setAgentId(null);
            setAgentLoading(false);
            setAgentError(null);
            return () => {
                cancelled = true;
            };
        }
        setAgentLoading(true);
        setAgentId(null);
        setAgentError(null);
        void setupWizardService
            .getJavaScriptToolAgent(selectedToolIdentity)
            .then((session) => {
            if (cancelled)
                return;
            setAgentId(session.agentId);
            setAgentLoading(false);
        })
            .catch((loadError) => {
            if (cancelled)
                return;
            setAgentId(null);
            setAgentLoading(false);
            setAgentError(loadError instanceof Error
                ? loadError.message
                : "Failed to load JavaScript tool assistant");
        });
        return () => {
            cancelled = true;
        };
    }, [selectedToolIdentity]);
    useEffect(() => {
        if (!agentId || agentLoading || !selectedToolIdentity)
            return;
        void syncAgentContext(agentId, selectedToolIdentity);
    }, [agentId, agentLoading, selectedToolIdentity, syncAgentContext]);
    const queueExternalRefresh = useCallback(() => {
        if (externalRefreshTimeoutRef.current !== null) {
            window.clearTimeout(externalRefreshTimeoutRef.current);
        }
        externalRefreshTimeoutRef.current = window.setTimeout(() => {
            externalRefreshTimeoutRef.current = null;
            void loadToolsRef.current?.(selectedToolIdRef.current);
        }, JAVA_SCRIPT_TOOL_EXTERNAL_REFRESH_DEBOUNCE_MS);
    }, []);
    useEffect(() => {
        if (!editContext?.itemsRepository) {
            return;
        }
        return editContext.itemsRepository.subscribeItemsChanged((changes) => {
            if (!isJavaScriptToolItemChange(changes, selectedToolIdRef.current)) {
                return;
            }
            queueExternalRefresh();
        });
    }, [editContext, queueExternalRefresh]);
    useEffect(() => {
        return () => {
            if (externalRefreshTimeoutRef.current !== null) {
                window.clearTimeout(externalRefreshTimeoutRef.current);
            }
        };
    }, []);
    const handleDeleteSelectedTool = useCallback(async () => {
        if (!selectedTool)
            return;
        if (!editContext?.confirm) {
            return;
        }
        editContext.confirm({
            header: "Delete JavaScript Tool",
            message: `Delete JavaScript tool '${selectedTool.name}'? This cannot be undone.`,
            acceptLabel: "Delete",
            showCancel: true,
            accept: async () => {
                try {
                    setDeleting(true);
                    await setupWizardService.deleteJavaScriptTool(selectedTool.id);
                    toast.success(`Deleted '${selectedTool.name}'`);
                    await loadTools();
                }
                catch (deleteError) {
                    const message = deleteError instanceof Error
                        ? deleteError.message
                        : "Failed to delete JavaScript tool";
                    toast.error(message);
                }
                finally {
                    setDeleting(false);
                }
            },
        });
    }, [editContext, loadTools, selectedTool]);
    const handleResetAssistant = useCallback(async () => {
        if (!selectedTool)
            return;
        try {
            setAgentResetting(true);
            setAgentError(null);
            const session = await setupWizardService.resetJavaScriptToolAgent(selectedTool.id);
            setAgentId(session.agentId);
            await syncAgentContext(session.agentId, selectedTool.id);
        }
        catch (resetError) {
            const message = resetError instanceof Error
                ? resetError.message
                : "Failed to restart the JavaScript tool assistant";
            setAgentError(message);
            toast.error(message);
        }
        finally {
            setAgentResetting(false);
        }
    }, [selectedTool, syncAgentContext]);
    const handleCreated = useCallback(async (toolId) => {
        await loadTools(toolId);
        toast.success("JavaScript tool created");
    }, [loadTools]);
    const toolsListContent = (_jsx("div", { className: "h-full overflow-auto p-4", children: _jsxs("div", { className: "flex min-h-[320px] flex-col overflow-hidden rounded-lg border border-gray-200 bg-white xl:min-h-0", children: [_jsxs("div", { className: "space-y-4 border-b border-gray-100 px-4 py-4", children: [_jsx("div", { className: "flex items-center justify-end gap-3", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsxs(Button, { size: "sm", onClick: () => setShowCreateDialog(true), disabled: state === "loading", children: [_jsx(Plus, { className: "h-4 w-4", strokeWidth: 1.5 }), "Add"] }), _jsx(Button, { size: "sm", variant: "ghost", onClick: () => void loadTools(selectedToolIdRef.current), disabled: state === "loading", children: _jsx(RefreshCw, { className: cn("h-4 w-4", state === "loading" && "animate-spin"), strokeWidth: 1.5 }) })] }) }), _jsxs("div", { className: "rounded border border-blue-200 bg-blue-50 px-3 py-2 text-xs text-blue-900", children: ["Custom JavaScript tools are stored under", _jsx("code", { className: "mx-1 rounded bg-blue-100 px-1 py-0.5 text-[11px]", children: "/sitecore/system/Parhelia/Settings/Ai Tools/Scripts" }), "and can be assigned like any other tool."] }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-gray-400", strokeWidth: 1.5 }), _jsx(Input, { type: "text", placeholder: "Search JavaScript tools...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "pl-9" })] }), error ? (_jsx("div", { className: "rounded border border-red-200 bg-red-50 p-2 text-xs whitespace-pre-wrap text-red-700", children: error })) : null] }), _jsx("div", { className: "min-h-0 flex-1 overflow-y-auto", children: filteredTools.length === 0 ? (_jsxs("div", { className: "flex h-full flex-col items-center justify-center px-6 py-12 text-center", children: [_jsx(FileCode2, { className: "mb-4 h-10 w-10 text-gray-300", strokeWidth: 1.25 }), _jsx("p", { className: "text-sm font-medium text-gray-600", children: tools.length === 0
                                    ? "No JavaScript tools yet"
                                    : "No matching JavaScript tools" }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: tools.length === 0
                                    ? "Create a custom JavaScript tool to expose a hidden script behind a normal tool signature."
                                    : "Try a different search term." })] })) : (_jsx("div", { className: "space-y-3 p-3", children: filteredTools.map((tool) => {
                            const isSelected = tool.id === selectedToolId;
                            return (_jsxs("button", { type: "button", onClick: () => setSelectedToolId(tool.id), className: cn("w-full rounded-lg border p-4 text-left transition-shadow hover:shadow-sm", isSelected
                                    ? "border-blue-400 bg-blue-50"
                                    : "border-gray-200 bg-white"), children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "truncate text-sm font-medium text-gray-900", children: tool.name }), _jsx("div", { className: cn("truncate text-[11px]", isSelected ? "text-blue-700" : "text-gray-500"), children: tool.path })] }), tool.needsConfiguration ? (_jsx("span", { className: cn("shrink-0 rounded-full px-2 py-0.5 text-[10px] font-medium", isSelected
                                                    ? "bg-blue-100 text-blue-800"
                                                    : "bg-amber-100 text-amber-800"), children: "Needs setup" })) : null] }), tool.description ? (_jsx("p", { className: cn("line-clamp-2 text-xs", isSelected ? "text-blue-900" : "text-gray-600"), children: tool.description })) : (_jsx("p", { className: cn("text-xs italic", isSelected ? "text-blue-700" : "text-gray-500"), children: "No description yet" }))] }, tool.id));
                        }) })) })] }) }));
    const detailsContent = (_jsx("div", { className: "h-full overflow-auto p-4", children: _jsx("div", { className: "flex min-h-[360px] flex-col overflow-hidden rounded-lg border border-gray-200 bg-white xl:min-h-0", children: selectedTool ? (_jsx("div", { className: "min-h-0 flex-1", children: _jsx(JavaScriptToolConfigPanel, { itemId: selectedTool.id, title: selectedTool.name, actions: _jsxs(Button, { variant: "outline", size: "sm", onClick: () => void handleDeleteSelectedTool(), disabled: deleting, title: "Delete selected JavaScript tool", children: [deleting ? (_jsx(RefreshCw, { className: "h-4 w-4 animate-spin", strokeWidth: 1.5 })) : (_jsx(Trash2, { className: "h-4 w-4", strokeWidth: 1.5 })), "Delete Tool"] }) }) })) : (_jsxs("div", { className: "flex h-full min-h-[360px] flex-col items-center justify-center gap-3 p-8 text-center xl:min-h-0", children: [_jsx(FileCode2, { className: "h-10 w-10 text-gray-300", strokeWidth: 1.25 }), _jsxs("div", { className: "space-y-1", children: [_jsx("div", { className: "text-sm font-medium text-gray-700", children: "Select a JavaScript tool" }), _jsx("div", { className: "text-xs text-gray-500", children: "Choose a tool from the list to edit its schema, script, and approval logic." })] })] })) }) }));
    const agentContent = selectedTool ? (_jsx("div", { className: "h-full overflow-auto p-4", children: _jsx("div", { className: "flex min-h-[360px] flex-col overflow-hidden rounded-lg border border-gray-200 bg-white xl:min-h-0", children: _jsx("div", { className: "min-h-0 flex-1", children: _jsx(JavaScriptToolAgentPanel, { toolName: selectedTool.name, agentId: agentId, loading: agentLoading, resetting: agentResetting, error: agentError, onStartOver: handleResetAssistant, headerStart: selectedTool.hasApprovalScript ? (_jsx("div", { className: "rounded-full bg-violet-100 p-1 text-violet-700", children: _jsx(ShieldAlert, { className: "h-3.5 w-3.5", strokeWidth: 1.5 }) })) : null }) }) }) })) : null;
    const panels = selectedTool
        ? [
            {
                name: "javascript-tools-list",
                defaultSize: 320,
                content: toolsListContent,
                className: "overflow-hidden",
            },
            {
                name: "javascript-tools-details",
                defaultSize: 520,
                content: detailsContent,
                className: "overflow-hidden",
            },
            {
                name: "javascript-tools-agent",
                defaultSize: 560,
                content: agentContent,
                className: "overflow-hidden",
            },
        ]
        : [
            {
                name: "javascript-tools-list",
                defaultSize: 320,
                content: toolsListContent,
                className: "overflow-hidden",
            },
            {
                name: "javascript-tools-details",
                defaultSize: 520,
                content: detailsContent,
                className: "overflow-hidden",
            },
        ];
    return (_jsxs(_Fragment, { children: [_jsx(Splitter, { panels: panels, localStorageKey: "javascript-tools-panel-splitter-v1", direction: "horizontal", className: "h-full", splitterClassName: "bg-gray-200 hover:bg-gray-300 w-[6px]" }), _jsx(CreateJavaScriptToolDialog, { open: showCreateDialog, onOpenChange: setShowCreateDialog, onCreated: handleCreated })] }));
}
export default JavaScriptToolsPanel;
//# sourceMappingURL=JavaScriptToolsPanel.js.map