import { jsx, jsxs } from "react/jsx-runtime";
import { memo, useEffect, useLayoutEffect, useRef, useState } from "react";
import { Button } from "@uipath/apollo-wind";
import { ChevronDown, ChevronLeft, ChevronRight, Plus, X } from "lucide-react";
import { ProbeResizeHandles } from "./ProbeResizeHandles.js";
import { useDragSession } from "./useDragSession.js";
import { useLatestRef } from "./useLatestRef.js";
function WatchValueView({ value, depth = 0 }) {
    if (null === value) return /*#__PURE__*/ jsx("span", {
        className: "text-[11px] font-mono text-foreground-subtle italic",
        children: "null"
    });
    if (void 0 === value) return /*#__PURE__*/ jsx("span", {
        className: "text-[11px] font-mono text-foreground-subtle italic",
        children: "undefined"
    });
    if ('string' == typeof value) return /*#__PURE__*/ jsxs("span", {
        className: "text-[11px] font-mono text-emerald-600 dark:text-emerald-400",
        children: [
            '"',
            value,
            '"'
        ]
    });
    if ('number' == typeof value) return /*#__PURE__*/ jsx("span", {
        className: "text-[11px] font-mono text-blue-600 dark:text-blue-400",
        children: String(value)
    });
    if ('boolean' == typeof value) return /*#__PURE__*/ jsx("span", {
        className: "text-[11px] font-mono text-violet-600 dark:text-violet-400",
        children: String(value)
    });
    if ('object' == typeof value) {
        const isArray = Array.isArray(value);
        const entries = isArray ? value.map((v, i)=>[
                String(i),
                v
            ]) : Object.entries(value);
        if (0 === entries.length) return /*#__PURE__*/ jsx("span", {
            className: "text-[11px] font-mono text-foreground-subtle",
            children: isArray ? '[]' : '{}'
        });
        if (depth >= 3) return /*#__PURE__*/ jsx("span", {
            className: "text-[11px] font-mono text-foreground-subtle",
            children: isArray ? `[…${entries.length}]` : '{…}'
        });
        return /*#__PURE__*/ jsx("div", {
            className: "pl-2 space-y-0.5",
            children: entries.map(([k, v])=>/*#__PURE__*/ jsxs("div", {
                    className: "flex gap-1 text-[11px] font-mono min-w-0",
                    children: [
                        /*#__PURE__*/ jsxs("span", {
                            className: "text-foreground-muted shrink-0",
                            children: [
                                k,
                                ":"
                            ]
                        }),
                        /*#__PURE__*/ jsx(WatchValueView, {
                            value: v,
                            depth: depth + 1
                        })
                    ]
                }, k))
        });
    }
    return /*#__PURE__*/ jsx("span", {
        className: "text-[11px] font-mono text-foreground-muted",
        children: String(value)
    });
}
function RemoveButton({ onRemove, label }) {
    return /*#__PURE__*/ jsx(Button, {
        variant: "ghost",
        size: "3xs",
        icon: true,
        onMouseDown: (e)=>e.stopPropagation(),
        onClick: onRemove,
        className: "opacity-0 group-hover:opacity-100 focus:opacity-100 transition-opacity shrink-0 self-center",
        title: label,
        "aria-label": label,
        children: /*#__PURE__*/ jsx(X, {})
    });
}
function DisclosureButton({ expanded, onToggle, label }) {
    return /*#__PURE__*/ jsx(Button, {
        variant: "ghost",
        size: "3xs",
        icon: true,
        onMouseDown: (e)=>e.stopPropagation(),
        onClick: onToggle,
        title: label,
        "aria-label": label,
        "aria-expanded": expanded,
        children: expanded ? /*#__PURE__*/ jsx(ChevronDown, {}) : /*#__PURE__*/ jsx(ChevronRight, {})
    });
}
function WatchRow({ watch, onChange, onRemove }) {
    const [expr, setExpr] = useState(watch.expression);
    const [expanded, setExpanded] = useState(true);
    useEffect(()=>{
        setExpr(watch.expression);
    }, [
        watch.expression
    ]);
    const commit = ()=>{
        if (expr !== watch.expression) onChange(expr);
    };
    return /*#__PURE__*/ jsxs("div", {
        className: "group px-2 py-1 border-b border-border-subtle last:border-b-0",
        children: [
            /*#__PURE__*/ jsxs("div", {
                className: "flex items-center gap-1 min-w-0",
                children: [
                    /*#__PURE__*/ jsx(DisclosureButton, {
                        expanded: expanded,
                        onToggle: ()=>setExpanded((e)=>!e),
                        label: "Toggle value"
                    }),
                    /*#__PURE__*/ jsx("input", {
                        value: expr,
                        onChange: (e)=>setExpr(e.target.value),
                        onBlur: commit,
                        onKeyDown: (e)=>{
                            e.stopPropagation();
                            if ('Enter' === e.key) commit();
                        },
                        placeholder: "e.g. output.items[0].id",
                        "aria-label": "Watch expression",
                        "data-probe-watch-input": "true",
                        className: "flex-1 min-w-0 text-sm font-mono text-foreground-secondary bg-transparent outline-none border-b border-transparent focus:border-foreground-accent"
                    }),
                    /*#__PURE__*/ jsx(RemoveButton, {
                        onRemove: onRemove,
                        label: "Remove watch"
                    })
                ]
            }),
            expanded && watch.hasValue && /*#__PURE__*/ jsx("div", {
                className: "pl-2 pt-0.5",
                children: /*#__PURE__*/ jsx(WatchValueView, {
                    value: watch.value
                })
            })
        ]
    });
}
const PAN_ON_SCROLL_SPEED = 0.5;
function ProbeCardComponent({ watches, iterationControl, onAddWatch, onUpdateWatch, onRemoveWatch, onDragStart, onDrag, onDragEnd, onResizeStart, onResize, onResizeEnd, onClose, onCanvasPan, onCanvasZoom }) {
    const [hovered, setHovered] = useState(false);
    const cardRef = useRef(null);
    const watchListRef = useRef(null);
    const pendingFocusNewWatchRef = useRef(false);
    const previousWatchCountRef = useRef(watches.length);
    const onCloseRef = useLatestRef(onClose);
    const onCanvasPanRef = useLatestRef(onCanvasPan);
    const onCanvasZoomRef = useLatestRef(onCanvasZoom);
    const isSpacePressedRef = useRef(false);
    const canvasPanCleanupRef = useRef(null);
    const canvasPanLastPointRef = useRef(null);
    const suppressNextClickRef = useRef(false);
    const handleHeaderMouseDown = useDragSession({
        onStart: onDragStart,
        onMove: onDrag,
        onEnd: onDragEnd
    });
    const handleAddWatch = ()=>{
        pendingFocusNewWatchRef.current = true;
        onAddWatch();
    };
    useLayoutEffect(()=>{
        const previousCount = previousWatchCountRef.current;
        previousWatchCountRef.current = watches.length;
        if (!pendingFocusNewWatchRef.current || watches.length <= previousCount) return;
        pendingFocusNewWatchRef.current = false;
        const inputs = watchListRef.current?.querySelectorAll('[data-probe-watch-input="true"]');
        const input = inputs?.[inputs.length - 1];
        if (!input) return;
        input.scrollIntoView({
            block: 'nearest'
        });
        input.focus({
            preventScroll: true
        });
    }, [
        watches.length
    ]);
    useEffect(()=>{
        const handler = (e)=>{
            const card = cardRef.current;
            if (!card || !card.contains(document.activeElement)) return;
            if ('Escape' === e.key) {
                e.stopPropagation();
                e.preventDefault();
                onCloseRef.current();
                return;
            }
            if ('ArrowDown' === e.key || 'ArrowUp' === e.key) {
                const inputs = Array.from(card.querySelectorAll('[data-probe-watch-input="true"]'));
                const idx = inputs.indexOf(document.activeElement);
                if (-1 === idx) return;
                const next = inputs['ArrowDown' === e.key ? idx + 1 : idx - 1];
                if (next) {
                    e.preventDefault();
                    e.stopPropagation();
                    next.focus();
                    next.select();
                }
                return;
            }
            if ('Delete' !== e.key && 'Backspace' !== e.key) return;
            const active = document.activeElement;
            const isEditable = !!active && ('INPUT' === active.tagName || 'TEXTAREA' === active.tagName || active.isContentEditable);
            if (isEditable) return;
            e.stopPropagation();
            e.preventDefault();
            onCloseRef.current();
        };
        window.addEventListener('keydown', handler, true);
        return ()=>window.removeEventListener('keydown', handler, true);
    }, [
        onCloseRef
    ]);
    useEffect(()=>{
        const handleKeyDown = (e)=>{
            if (' ' === e.key || 'Space' === e.code) isSpacePressedRef.current = true;
        };
        const handleKeyUp = (e)=>{
            if (' ' === e.key || 'Space' === e.code) isSpacePressedRef.current = false;
        };
        window.addEventListener('keydown', handleKeyDown, true);
        window.addEventListener('keyup', handleKeyUp, true);
        return ()=>{
            window.removeEventListener('keydown', handleKeyDown, true);
            window.removeEventListener('keyup', handleKeyUp, true);
            canvasPanCleanupRef.current?.();
        };
    }, []);
    const startCanvasPan = (e)=>{
        if (!onCanvasPanRef.current) return;
        e.stopPropagation();
        e.preventDefault();
        suppressNextClickRef.current = true;
        canvasPanCleanupRef.current?.();
        canvasPanLastPointRef.current = {
            x: e.clientX,
            y: e.clientY
        };
        const handleMove = (ev)=>{
            const last = canvasPanLastPointRef.current;
            if (!last) return;
            const next = {
                x: ev.clientX,
                y: ev.clientY
            };
            canvasPanLastPointRef.current = next;
            onCanvasPanRef.current?.({
                x: next.x - last.x,
                y: next.y - last.y
            });
        };
        const handleUp = ()=>{
            window.removeEventListener('mousemove', handleMove);
            window.removeEventListener('mouseup', handleUp);
            canvasPanCleanupRef.current = null;
            canvasPanLastPointRef.current = null;
            window.setTimeout(()=>{
                suppressNextClickRef.current = false;
            }, 0);
        };
        canvasPanCleanupRef.current = handleUp;
        window.addEventListener('mousemove', handleMove);
        window.addEventListener('mouseup', handleUp);
    };
    const handleMouseDownCapture = (e)=>{
        const target = e.target instanceof Element ? e.target : null;
        const startedMiddlePan = 1 === e.button;
        const startedSpacePan = 0 === e.button && isSpacePressedRef.current && !isInteractiveTarget(target);
        if (startedMiddlePan || startedSpacePan) return void startCanvasPan(e);
        if (0 === e.button && !isInteractiveTarget(target)) cardRef.current?.focus();
    };
    const handleClickCapture = (e)=>{
        if (!suppressNextClickRef.current) return;
        suppressNextClickRef.current = false;
        e.stopPropagation();
        e.preventDefault();
    };
    useEffect(()=>{
        const card = cardRef.current;
        if (!card) return;
        const onWheel = (e)=>{
            if (e.ctrlKey) {
                if (onCanvasZoomRef.current) {
                    e.stopPropagation();
                    e.preventDefault();
                    onCanvasZoomRef.current({
                        clientX: e.clientX,
                        clientY: e.clientY,
                        deltaY: e.deltaY,
                        deltaMode: e.deltaMode,
                        ctrlKey: e.ctrlKey
                    });
                }
                return;
            }
            const target = e.target instanceof Node ? e.target : null;
            if (target && watchListRef.current?.contains(target) && canScrollVertically(watchListRef.current, e.deltaY)) return void e.stopPropagation();
            if (onCanvasPanRef.current) {
                e.stopPropagation();
                e.preventDefault();
                const deltaNormalize = 1 === e.deltaMode ? 20 : 1;
                let deltaX = e.deltaX * deltaNormalize;
                let deltaY = e.deltaY * deltaNormalize;
                if (!isMac() && e.shiftKey) {
                    deltaX = e.deltaY * deltaNormalize;
                    deltaY = 0;
                }
                onCanvasPanRef.current({
                    x: -deltaX * PAN_ON_SCROLL_SPEED,
                    y: -deltaY * PAN_ON_SCROLL_SPEED
                });
            }
        };
        card.addEventListener('wheel', onWheel, {
            passive: false
        });
        return ()=>card.removeEventListener('wheel', onWheel);
    }, [
        onCanvasZoomRef,
        onCanvasPanRef
    ]);
    return /*#__PURE__*/ jsxs("div", {
        ref: cardRef,
        tabIndex: 0,
        role: "group",
        "aria-label": "Probe",
        className: "relative h-full flex flex-col rounded-[20px] border border-dashed border-border bg-surface-raised shadow-sm outline-none focus-visible:ring-2 focus-visible:ring-foreground-accent-muted nodrag",
        onMouseDownCapture: handleMouseDownCapture,
        onClickCapture: handleClickCapture,
        onMouseDown: (e)=>e.stopPropagation(),
        onClick: (e)=>e.stopPropagation(),
        onKeyDown: (e)=>e.stopPropagation(),
        onMouseEnter: ()=>setHovered(true),
        onMouseLeave: ()=>setHovered(false),
        children: [
            /*#__PURE__*/ jsxs("div", {
                onMouseDown: handleHeaderMouseDown,
                className: "flex items-center gap-2 px-3 py-2 border-b border-border-subtle bg-surface-overlay/30 cursor-move select-none shrink-0",
                children: [
                    /*#__PURE__*/ jsx("span", {
                        className: "min-w-0 flex-1 truncate text-xs font-semibold text-foreground",
                        children: "Probe"
                    }),
                    iterationControl && /*#__PURE__*/ jsxs("div", {
                        className: "flex items-center gap-0.5 shrink-0",
                        children: [
                            /*#__PURE__*/ jsx(Button, {
                                variant: "ghost",
                                size: "3xs",
                                icon: true,
                                disabled: 0 === iterationControl.current,
                                onMouseDown: (e)=>e.stopPropagation(),
                                onClick: iterationControl.onPrev,
                                title: "Previous iteration",
                                "aria-label": "Previous iteration",
                                children: /*#__PURE__*/ jsx(ChevronLeft, {})
                            }),
                            /*#__PURE__*/ jsxs("span", {
                                className: "text-[10px] font-mono text-foreground-subtle tabular-nums select-none",
                                children: [
                                    iterationControl.current + 1,
                                    "/",
                                    iterationControl.total
                                ]
                            }),
                            /*#__PURE__*/ jsx(Button, {
                                variant: "ghost",
                                size: "3xs",
                                icon: true,
                                disabled: iterationControl.current === iterationControl.total - 1,
                                onMouseDown: (e)=>e.stopPropagation(),
                                onClick: iterationControl.onNext,
                                title: "Next iteration",
                                "aria-label": "Next iteration",
                                children: /*#__PURE__*/ jsx(ChevronRight, {})
                            })
                        ]
                    }),
                    /*#__PURE__*/ jsx(Button, {
                        variant: "ghost",
                        size: "3xs",
                        icon: true,
                        onMouseDown: (e)=>e.stopPropagation(),
                        onClick: handleAddWatch,
                        title: "Add watch",
                        "aria-label": "Add watch",
                        children: /*#__PURE__*/ jsx(Plus, {})
                    }),
                    /*#__PURE__*/ jsx(Button, {
                        variant: "ghost",
                        size: "3xs",
                        icon: true,
                        onMouseDown: (e)=>e.stopPropagation(),
                        onClick: onClose,
                        title: "Remove probe",
                        "aria-label": "Remove probe",
                        children: /*#__PURE__*/ jsx(X, {})
                    })
                ]
            }),
            /*#__PURE__*/ jsx("div", {
                ref: watchListRef,
                className: "flex-1 min-h-0 overflow-y-auto",
                children: 0 === watches.length ? /*#__PURE__*/ jsx("div", {
                    className: "flex items-center justify-center h-full px-4",
                    children: /*#__PURE__*/ jsx("span", {
                        className: "text-[11px] text-foreground-subtle text-center leading-relaxed",
                        children: "No watches — use + to add one"
                    })
                }) : watches.map((w)=>/*#__PURE__*/ jsx(WatchRow, {
                        watch: w,
                        onChange: (expr)=>onUpdateWatch(w.id, expr),
                        onRemove: ()=>onRemoveWatch(w.id)
                    }, w.id))
            }),
            /*#__PURE__*/ jsx(ProbeResizeHandles, {
                active: hovered,
                onResizeStart: onResizeStart,
                onResize: onResize,
                onResizeEnd: onResizeEnd
            })
        ]
    });
}
const ProbeCard = /*#__PURE__*/ memo(ProbeCardComponent);
function isInteractiveTarget(target) {
    return !!target?.closest('input, textarea, select, button, a, [contenteditable], [role="button"], [role="menuitem"]');
}
function isMac() {
    return "u" > typeof navigator && navigator.userAgent.includes('Mac');
}
function canScrollVertically(element, deltaY) {
    if (0 === deltaY) return false;
    const maxScrollTop = element.scrollHeight - element.clientHeight;
    if (maxScrollTop <= 0) return false;
    return deltaY < 0 ? element.scrollTop > 0 : element.scrollTop < maxScrollTop;
}
export { ProbeCard };
