import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { Loader2 } from "lucide-react";
import { useEffect, useMemo, useRef, useState } from "react";
import { useEditContext } from "../client/editContext";
import { AlertCircle } from "lucide-react";
import { Popover, PopoverContent, PopoverTrigger, } from "../../components/ui/popover";
export function FieldActionIndicator({ action, pageViewContext, }) {
    const editContext = useEditContext();
    if (!editContext)
        return null;
    const effectivePageViewContext = pageViewContext ?? editContext.getActiveSlotContext()?.primaryPageViewContext;
    if (!effectivePageViewContext)
        return null;
    const field = action.field;
    const fieldElements = effectivePageViewContext.editorIframe?.contentWindow?.document.querySelectorAll(`[data-fieldid="${field.fieldId}"][data-itemid="${field.item.id}"][data-language="${field.item.language}"][data-version="${field.item.version}"]`);
    if (!fieldElements)
        return null;
    return (_jsx(_Fragment, { children: [...fieldElements].map((element, index) => (_jsx(SingleIndicator, { element: element, action: action }, action.field.fieldId + action.field + index))) }));
}
function SingleIndicator({ element, action, }) {
    const editContext = useEditContext();
    // Track bounds so the indicator follows the field while the iframe scrolls.
    const [indicatorRect, setIndicatorRect] = useState(null);
    const rafRef = useRef(null);
    const ownerDoc = element.ownerDocument;
    const ownerWin = ownerDoc.defaultView ?? null;
    const scrollContainer = useMemo(() => {
        return ownerDoc.scrollingElement ?? ownerDoc.documentElement ?? ownerDoc.body;
    }, [ownerDoc]);
    useEffect(() => {
        const update = () => {
            try {
                setIndicatorRect(element.getBoundingClientRect());
            }
            catch {
                setIndicatorRect(null);
            }
        };
        const scheduleUpdate = () => {
            if (rafRef.current != null)
                window.cancelAnimationFrame(rafRef.current);
            rafRef.current = window.requestAnimationFrame(() => {
                rafRef.current = null;
                update();
            });
        };
        update();
        scrollContainer?.addEventListener("scroll", scheduleUpdate, {
            passive: true,
        });
        ownerWin?.addEventListener("scroll", scheduleUpdate, { passive: true });
        ownerWin?.addEventListener("resize", scheduleUpdate);
        let ro = null;
        try {
            ro = new ResizeObserver(scheduleUpdate);
            ro.observe(element);
        }
        catch {
            ro = null;
        }
        return () => {
            if (rafRef.current != null) {
                window.cancelAnimationFrame(rafRef.current);
                rafRef.current = null;
            }
            scrollContainer?.removeEventListener("scroll", scheduleUpdate);
            ownerWin?.removeEventListener("scroll", scheduleUpdate);
            ownerWin?.removeEventListener("resize", scheduleUpdate);
            try {
                ro?.disconnect();
            }
            catch { }
        };
    }, [element, ownerWin, scrollContainer]);
    if (!indicatorRect)
        return null;
    const isRunning = action.state === "running";
    const isError = action.state === "error";
    return (_jsxs("div", { className: `${isRunning ? "focus-shadow executing-action bg-theme-secondary/20" : ""} pointer-events-none absolute`, style: {
            left: indicatorRect.x,
            top: indicatorRect.y,
            width: indicatorRect.width,
            height: indicatorRect.height,
            zIndex: 800,
        }, children: [isRunning && (_jsx("div", { className: "text-theme-secondary rounded-mdp-3 bg-theme-secondary-light border-theme-secondary text-3xs pointer-events-none absolute top-1/2 left-1/2 flex -translate-x-1/2 -translate-y-1/2 flex-col items-center justify-center gap-1.5 rounded border p-1 font-bold", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), action.message && _jsx("div", { className: "text-3xs", children: action.message })] }) })), isError && (_jsx("div", { className: "pointer-events-auto absolute top-1 right-1", children: _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx("button", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-red-50 text-red-600 shadow-sm ring-1 ring-red-200 hover:bg-red-100", "aria-label": "Show error", children: _jsx(AlertCircle, { strokeWidth: 1, className: "h-3.5 w-3.5" }) }) }), _jsxs(PopoverContent, { align: "end", side: "top", className: "w-80 p-2", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertCircle, { strokeWidth: 1, className: "mt-0.5 h-4 w-4 text-red-600" }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "text-sm font-medium text-red-700", children: action.label || "Error" }), action.message && (_jsx("div", { className: "mt-1 text-xs break-words whitespace-pre-wrap text-gray-700", children: action.message }))] })] }), _jsx("div", { className: "mt-2 flex justify-end", children: _jsx("button", { className: "rounded border border-gray-300 px-2 py-1 text-xs hover:bg-gray-50", onClick: (e) => {
                                            e.stopPropagation();
                                            if (editContext)
                                                editContext.dismissFieldAction(action.field);
                                        }, "data-testid": "field-action-error-dismiss", children: "Dismiss" }) })] })] }) }))] }));
}
//# sourceMappingURL=FieldActionIndicator.js.map